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 :

Template, héritage multiple et redéfinition


Sujet :

Langage C++

  1. #1
    Membre du Club
    Inscrit en
    Juin 2002
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 37
    Points : 42
    Points
    42
    Par défaut Template, héritage multiple et redéfinition
    Bonjour !

    Voici le code qui me pose un problème :
    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
     
    #include <iostream>
     
    using namespace std;
     
    template <class T>
    struct Mother {
        void func(T val) {
            cout << val << endl;
        }
    };
     
    struct Child : public Mother<int>, public Mother<double> {  
    };
     
    int main(int argc, char** argv) {
        Child c;
        c.Mother<int>::func(314);    
        return 0;
    };
    Ce code fonctionne très bien en l'état. Mon problème est que je voudrais redéfinir dans "Child" la méthode "func" issu de l'héritage "Mother<int>".

    Si je fais...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct Child : public Mother<int>, public Mother<double> {  
        void func(int val) {
            cout << "Fonctionnalité supplémentaire" << endl;
            Mother<int>::func(val);
        }
    };
    ... ça compile très bien mais ça ne fait pas ce que je veux car, en fait, cela ne redéfinit pas la méthode "func" issu de l'héritage "Mother<int>". Ainsi, si j'appelle "c.Mother<int>::func(314)" dans la fonction "main", seule la méthode "func" de la classe de base "Mother<int>" est appelée !

    En fait, je voudrais faire quelque chose dont la syntaxe pourrait être...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct Child : public Mother<int>, public Mother<double> {  
        void Mother<int>::func(int val) {
            cout << "Fonctionnalité supplémentaire" << endl;
            Mother<int>::func(val);
        }
    };
    ... malheureusement, cette syntaxe n'est pas acceptée par les compilateurs :
    G++ me dit : "error: cannot declare member function `Mother<int>::func' within `Child'"
    et Visual C++ : "error C3240: 'func' : must be a non-overloaded abstract member function of 'Mother<T>'"

    Merci pour vos réponses !

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Si tu veux supplanter une fonction, il faut qu'elle soit virtuelle (donc ajouter virtual à Mother<T>::func)

    Si tu veux pouvoir supplanter une fonction qui est ambigue car héritée deux fois, il me semble (mais je ne suis pas un champion de l'héritage multiple, j'ai plutôt tendance à choisir les alternatives) qu'il n'y a pas d'autres solutions que d'introduire un niveau de hiérarchie supplémentaire qui fournit un renommage. (Donc introduire une classe MotherInt qui renomme func en funcInt).

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Points : 542
    Points
    542
    Par défaut
    Ne faudrait-il pas tout simplement que func soit virtuelle ??

    EDIT: grilled

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par Paul Atreide
    cela ne redéfinit pas la méthode "func" issu de l'héritage "Mother<int>". Ainsi, si j'appelle "c.Mother<int>::func(314)" dans la fonction "main", seule la méthode "func" de la classe de base "Mother<int>" est appelée !
    Ça redéfinit bien la fonction func de la classe mère, mais ton appel n'est pas correct : quand tu dis "c.Mother<int>::func(314)", tu appelles explicitement la fonction de la classe mère. Si tu appelles "c.func(314)" tu auras le comportement attendu.

    De plus, comme disent Jean-Marc et rigobert, une fonction destinée à être supplantée devrait être déclarée virtuelle si tu veux pouvoir bénéficier du polymorphisme.

  5. #5
    Membre du Club
    Inscrit en
    Juin 2002
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 37
    Points : 42
    Points
    42
    Par défaut
    Merci pour vos réponses.

    J'ai finalement opté pour une solution de la forme suivante :

    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
     
    #include <iostream>
     
    using namespace std;
     
    struct MotherInt {
        virtual void funcInt(int val) {
            cout << val << endl;
        }
    };
     
    struct MotherDouble {
        virtual void funcDouble(double val) {
            cout << val << endl;
        }
    };
     
    struct Child : public MotherInt, public MotherDouble {
        void funcInt(int val) {
            cout << "Fonctionnalités supplémentaires" << endl;
            MotherInt::funcInt(val);
        }
    };
     
    int main(int argc, char** argv) {
        Child c;
        c.funcInt(314);
        return 0;
    };

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 380
    Points : 41 576
    Points
    41 576
    Par défaut
    (enfin, dans le cas présent, la virtualité n'est pas utilisée: ça marcherait aussi bien sans virtual...)

    Dans ce cas-ci par contre, virtual est indispensable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(int argc, char** argv) {
        MotherInt *pc = new Child;
        pc->funcInt(314);
        delete pc;
        return 0;
    };

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 26/10/2010, 11h33
  2. [heritage][conception]héritage multiple en java!
    Par soulhouf dans le forum Langage
    Réponses: 9
    Dernier message: 25/08/2005, 20h03
  3. L'héritage multiple est-il possible en Delphi ?
    Par SchpatziBreizh dans le forum Langage
    Réponses: 8
    Dernier message: 30/06/2005, 11h30
  4. utilisez vous l'héritage multiple ?
    Par vodosiossbaas dans le forum C++
    Réponses: 8
    Dernier message: 13/06/2005, 20h25
  5. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55

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