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

C++ Discussion :

Héritage d'une classe 'templatisé' typé


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 3
    Points
    3
    Par défaut Héritage d'une classe 'templatisé' typé
    Bonjour,

    J'aurais aimé savoir si il est possible d'une manière ou d'une autre de faire l'héritage d'une classe ayant un template en la typant directement.

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T>
    class A
    {
         A();
         ~A();
    }
    class B : public A<B>
    {
        B():A<B>::A(){};
        ~B();
    }
    J'ai testé sa aussi mais sa ne fonctionne pas non plus, je ne comprends pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T>
    class A
    {
         A();
         ~A();
    }
    class B : public A<B>
    {
        B():A<B>(){};
        ~B();
    }
    J'ai effectué ce code mais à chaque fois, lorsque je compile je reçois plusieurs fois les messages d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    undefined reference to 'A<B>::A()' 
    undefined reference to 'A<B>::~A()'


    Je travaille avec CodeBlocks sous windows et compile avec g++ 3.4.5

  2. #2
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    Plusieurs probs.

    A<T>::A() et A<T>::~A() n'ont pas de definitions, juste des déclarations.

    Comme ce sont des membres privés, il ne sont pas accessibles de B par un héritage publique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template <class T>
    class A
    {
    protected: // ajout visibility
      A(){};   // ajout definition
      ~A(){};
    };
     
    class B : public A<B>
    {
    public:
      B():A<B>::A(){};
      ~B(){};
    };

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class B : public A<B>
    {
    public:
      B()
      :A<B>()
      {}
      ~B()
      {}
    };
    Suffit (pas besoin de A<B>::A()).

    Si tu veux appeler le constructeur par défaut, alors pas besoin de le préciser dans B, il est de toute façon automatiquement appelé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class B : public A<B>
    {
    public:
      B() // appel implicite à A<B>()
      {}
      ~B()
      {}
    };

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut, et bienvenue sur le forum.

    Lorsque tu as un message proche de "undefined reference to (une fonction ou une fonction membre)", il s'agit d'un message envoyé par l'éditeur de liens qui te dit, en gros qu'il ne trouve pas le code exécutable de la fonction vers laquelle il doit faire pointer un appel.

    Il peut y avoir deux raisons à cela:

    1. Soit, tu n'a, purement et simplement, pas implémenté la dite fonction.
    2. Soit tu travailles avec une classe template et le compilateur n'a pas trouvé le code (C++) de la fonction afin de créer une version exécutable correspondant au type réel du paramètre template.
    Dans le premier cas, il faut, tout simplement, veiller à implémenter la fonction manquante.

    Dans le deuxième cas, c'est sans doute parce que tu as définis la fonction indiquée (ici template<class T> A<T>::A(){/* ce qu'il faut faire*/} ) dans un fichier séparé qui n'est pas accessible au compilateur au moment où il rencontre l'appel à cette fonction et qu'il devrait donc créer une version du constructeur de A utilisant un B.

    La solution la plus simple à ce problème consiste, comme l'a proposé metagoto, à donner la définition des fonctions directement dans la définition de la classe, mais il est également possible de "déporter" l'implémentation des fonctions dans un fichier séparé (dont il est préférable que l'extension ne soit pas *.cpp afin d'éviter les confusions), que tu devras alors veiller à inclure chaque fois que le compilateur doit être en mesure de créer une version ad-hoc des différentes fonctions.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Déja merci à tous pour vos réponses et merci koala01 pour le bienvenue,

    Pour metagoto :
    excuse moi, je n'avais pas préciser que j'avais mis les constructeurs et destructeurs en public.

    Sinon pour koala01 :
    Pour le premier cas : j'avais bien défini mes fonctions
    Pour le deuxième cas : j'avais rencontré le problème et avais essayé de le contourner en mettant tout dans le .h de la classe B.

    Mais en faite je me suis aperçu que le problème venait d'ailleurs, je passerais l'explication car celà serait peut-être compliqué à expliquer... (en gros j'essayais d'instancier ma classe A avec un type void dans une autre classe C, et après quelque recherche je me suis aperçu que celà n'étais pas possible...)

    J'ai donc enlevé le template de ma classe A ce qui à résolu le problème, j'aurais juste à redéfinir une fonction dans chacune de mes classe héritant de ma classe A...

    Mais j'ai quand même un autre problème, de surcharge d'opérateur =, lorsque je l'utilise il n'utilise pas ma surcharge, peut être pourrez vous m'éclairer.
    J'ai ceci comme classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A
    {
        public :
            //blabla
            A *operator =(A* variable);
    }
    
    A *A::operator =(A* variable)
    {
        //code à exécuter plus un cout pour voir si il passe bien dans ma méthode
        return variable;
    }
    et dans mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main()
    {
        A* ptA1 = new A();
        A* ptA2 = new A();
        ptA1 = ptA2;
    
        return 1;
    }
    et lorsque je lance le programme, je ne vois rien qui apparait dans la console...

    Sinon est ce que l'opérateur d'affectation est hérité lorsque je fais un héritage de ma classe A

    Si j'écris :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class B : A
    {
        public :
            //blabla
    }
    et dans mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main()
    {
        B* ptB1 = new B();
        B* ptB2 = new B();
        ptB1 = ptB2;
    
        return 1;
    }
    est ce que (si le code de la classe A marchait...) celà fonctionnerait pour B aussi? Est ce que je verrais aussi le message en console?

  6. #6
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Bonjour,

    en fait l'opérateur = que vous avez défini ne marche que pour un cas tel que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    A a1;
    A a2;
     
    a1 = &a2;
    mais pas pour le cas normal qui est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    A a1;
    A a2;
     
    a1 = a2;
    bref il est mal défini et devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    A operator=(const A & v);

  7. #7
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    j'avais oublié, dans le cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A* ptA1 = new A();
    A* ptA2 = new A();
    ptA1 = ptA2;
    aucun opérateur ne sera appelé, vous ne faites que recopier un pointeur dans un autre

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Merci pour la réponse.

    Dans ce cas la si je veux surcharger la copie du pointeur est ce que je peux écrire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void operator =(void*, void*);
    En faite je l'ai déjà testé, et je sais que sa ne marche pas. Je récupère cette erreur à la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    error: `void operator=(void*, void*)' must be a nonstatic member function
    Dois je supposer que l'on ne peut pas surcharger l'opérateur de copie de pointeur?

  9. #9
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    vous ne pouvez pas surcharger la copie de pointeur, celle-ci étant indépendante du type pointé

    Citation Envoyé par zarwa Voir le message
    Je récupère cette erreur à la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    error: `void operator=(void*, void*)' must be a nonstatic member function
    l'opérateur = ne peut être un opérateur de classe (static) car cela n'a pas de sens

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    C'est pas faux, merci en tout cas pour toutes vos réponses

    Il y a t-il un moyen de changer le titre vu que les réponses ne correspondent pas du tout au titre? ou alors je supprime le post?

  11. #11
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    je ne pense pas qu'on puisse modifier le titre

    si vous voulez supprimer la discussion vous n'avez qu'a utiliser le bouton "delestage" qui apparait sous la dernière réponse (celle ci donc), et la discussion sera retirer très prochainement (ce n'est pas instantané)

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Surtout, tu ne supprimes pas la discussion, le forum servant entre autres comme base de connaissance à de nombreuses personnes

    Par contre, essaye de modifier ta première intervention, normalement, tu devrais pouvoir modifier le titre.

    Si toi tu ne peux pas le faire, c'est en mon pouvoir

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par zarwa Voir le message
    C'est pas faux, merci en tout cas pour toutes vos réponses

    Il y a t-il un moyen de changer le titre vu que les réponses ne correspondent pas du tout au titre? ou alors je supprime le post?
    Tu as un bouton Editer sur ton premier message de la discussion. De là tu pourras modifier le titre.

Discussions similaires

  1. Conception: héritage d'une classe abstraite
    Par Kikito dans le forum Langage
    Réponses: 19
    Dernier message: 05/10/2006, 17h36
  2. Héritage d'une class "primaire"
    Par sloshy dans le forum Général Python
    Réponses: 6
    Dernier message: 06/05/2006, 15h24
  3. Réponses: 14
    Dernier message: 02/02/2006, 18h32
  4. Héritage d'une classe en css
    Par picomz dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 27/12/2005, 16h10
  5. Héritage d'une classe thread
    Par SamCB500 dans le forum MFC
    Réponses: 4
    Dernier message: 07/07/2005, 15h35

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