IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Problème forward declaration


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Août 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème forward declaration
    Bonjour,
    je me suis remis au C++ après une longue periode de Java et je tombe vraiment de haut :waw:.
    En effet avec les pointeurs, les références et variable 'classique' je mis perd mais la n'est pas le problème :p.

    Pour faire simple, voici le code en question :
    TabView.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #ifndef TABVIEW_H
    #define TABVIEW_H
     
    #include "constantes.h"
    #include "enfantsmanager.h"
    #include "enfant.h"
     
    namespace Ui {
    class TabView;
    }
     
    class TabView : public QWidget
    {
        Q_OBJECT
     
    public:
        explicit TabView(QStandardItemModel* model, QStringList const& header, QWidget *parent = 0);
        void addLine(QString header, QStringList entry);
        ~TabView();
     
    signals:
        void itemSelected(QModelIndex index, bool* cancel);
        void itemChanged(QStandardItem* item, bool* cancel);
     
    public slots:
        virtual void on_itemSelected(QModelIndex index) = 0;
        virtual void on_itemChanged(QStandardItem* item, bool* cancel) = 0;
     
    private slots:
        void on_itemChanged(QStandardItem* item);
        void on_dataChanged(QModelIndex i1, QModelIndex i2);
     
    protected:
        Ui::TabView *ui;
        int m_line;
        QStandardItemModel *m_model;
        QStringList m_vHeader;
     
    private:
        QList<QStringList*> m_viewData;
        bool m_ignoreNextModify;
    };
     
    #endif // TABVIEW_H
    TabEnfants.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #ifndef TABENFANTS_H
    #define TABENFANTS_H
     
    #include "constantes.h"
    #include "tabview.h"
     
    class TabView;
     
    class TabEnfants : public TabView {
        Q_OBJECT
     
    public:
        TabEnfants(QStandardItemModel* model, QStringList const& header, QWidget *parent = 0);
        static QString getNiveauTxt(int galop);
     
    public slots:
        virtual void on_itemSelected(QModelIndex index);
        virtual void on_itemChanged(QStandardItem* item, bool* cancel);
    };
     
    #endif // TABENFANTS_H
    Les erreurs :
    • invalid use of incomplete type 'class TabView'
    • forward declaration of 'class TabView' (cette erreur disparais si j'enleve la ligne 7 de TabEnfants.h mais dans ce qu'a j'ai l'erreur "expected class-name before '{' token")


    Merci d'avance pour votre aide

  2. #2
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 713
    Points : 2 361
    Points
    2 361
    Par défaut
    Bonsoir.

    Dans TabEnfants tu a deux déclaration de TabView, l'une venant de l'include, et une autre forward.
    Comme TabEnfants hérite de TabView, la forward declaration ne suffit pas, il faut la déclaration de toute la classe, celle fournie par l'include.
    Cette dernière fournit une classe UI::TabView, donc si tu changes la déclaration de TabEnfants en class TabEnfants : public Ui::TabView et que tu supprimes class TabView;, je pense que ça devrait fonctionner.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Août 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Tout d'abord merci de ta réponse mais je ne pense pas que ça puisse marché puisque je veux que TabEnfants hérite de TabView et non de Ui::TabView (qui sont 2 classes différentes).

    Edit: je ne comprend vraiment pas d'où viens l'erreur puisque j'include TabView.h ...

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut, ça ne fonctionnera pas comme ça, pour que ça fonctionne tu dois ; (En imaginant avoir une classe et une autre qui inclu une autre) :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifndef TABVIEW
    #define TABVIEW
    class TabView;
    class TabEnfant {
    };

    Juste déclarer la classe TabView dans le .h mais ne pas inclure tabenfant dans le .h, par contre tu devras l'inclure dans le .cpp.

    Et dans l'autre le fichier qtablview.h tu n'as qu'à inclure QTabEnfant.h

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    As-tu retiré la forward declaration? Puisque tu inclus tabview.h elle ne sert pas, et elle pourrait bien cacher la déclaration de la classe et provoquer ton erreur. Pour hériter d'une classe, en effet, il faut comme le dit manudiclemente disposer de la déclaration complète, non d'une simple forward.
    Pour te la faire simple, la forward declaration dit simplement "ce type existe". Donc ça ne suffit que si tu n'utilises pas de membres (ni variables, ni fonctions, constructeurs et destructeurs y compris).
    De fait, ça ne permet que de déclarer des pointeurs ou des références du type déclaré (comme variables, arguments de fonctions, types de retour).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Oui ça aussi, tu dois t'assurer que aucune instanciation par défaut n'est effectuée dans le .h donc l'idéal c'est d'utiliser un pointeur ou une référence.

    Car pour instancier ou bien utiliser une fonction le compilateur à besoin de la définition complète de la classe. (la déclaration à elle seule ne suffit pas)

    C'est pour ça que je t'ai proposé d'inclure le .h dans le .cpp pour ne pas venir perturber la forward déclaration dans le .h

  7. #7
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    je donnais ces restrictions pour que l'OP comprenne mieux les forward decalrations, mais dans la mesure où il souhaite un héritage public, la solution à son problème est probablement de supprimer la forward declaration et d'inclure le header TabView.h dans le header TabEnfants.h

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par therwald Voir le message
    De fait, ça ne permet que de déclarer des pointeurs ou des références du type déclaré (comme variables, arguments de fonctions, types de retour).
    Ça peut aussi déclarer une fonction prenant en argument par copie de ce type.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Ça peut aussi déclarer une fonction prenant en argument par copie de ce type.
    Pas besoin de vérifier la visibilité du constructeur pour ça?

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Ça sera éventuellement fait lors de la définition de la fonction.

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par gregleboss50 Voir le message
    Les erreurs :
    • invalid use of incomplete type 'class TabView'
    • forward declaration of 'class TabView' (cette erreur disparais si j'enleve la ligne 7 de TabEnfants.h mais dans ce qu'a j'ai l'erreur "expected class-name before '{' token")


    Merci d'avance pour votre aide
    Un piège relativement classique, en particulier avec qtcreator, est que les headers guards (le #ifndef TABVIEW_H ) générés par défaut ne tiennent pas compte du namespace / de l’emplacement du fichier --> potentiellement, tu te retrouves avec deux fichiers qui ont le même, et ce même alors leurs classes sont différentes car dans des namespaces différents --> toujours mettre le nom du namespace dans le #ifndef/#define.

    L’autre possibilité, c’est que ton fichier enfant.h se retrouve, d’une manière ou d’une autre, à inclure lui-même le fichier tabview.h. Dans ce cas, si tu y réfléchis, le compilateur va se retrouver à essayer d’inclure tabview.h, mais ne pas le faire car TABVIEW_H est défini, et donc, se retrouve ensuite à inclure la définition de la classe TabEnfants sans connaître celle de TabView, puisqu’elle se retrouvera après (si tu compiles avec gcc, un gcc -E sur le fichier qui pose problème te permettra peut-être de mieux visualiser la chose. C’est possible aussi avec Visual, mais je ne connais pas l’option).

    De manière générale, ton #include "enfants.h" est louche au niveau de tabview : il n’y a rien dans ce que tu montres qui le nécessite. Et enfin, le nom du fichier qui pose problème à la compilation (le .cpp) est un indice très fort du problème : n’hésite pas à le mettre avec, ainsi que l’ordre dans lequel il fait ses #include.

Discussions similaires

  1. Problème de forward declaration
    Par le_ptit_lutin dans le forum C++
    Réponses: 10
    Dernier message: 02/07/2012, 17h55
  2. Problème de "forward declaration"
    Par oodini dans le forum C++
    Réponses: 8
    Dernier message: 09/03/2009, 18h05
  3. Problème déclaration anticipée (forward declaration)
    Par lilmeth dans le forum Débuter
    Réponses: 4
    Dernier message: 05/11/2008, 02h02
  4. Réponses: 6
    Dernier message: 14/02/2006, 11h29
  5. Problème de declaration de variable (API Win32)
    Par barbarello dans le forum Windows
    Réponses: 2
    Dernier message: 30/01/2006, 09h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo