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 :

pb Héritage multiple


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Par défaut pb Héritage multiple
    J'ai à utiliser des objets de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // classe  de bases : 
    class Obj_Base
    {
    };
    class Node
    {
    };
     
    // classe instanciées :
    class Obj_1 : public Node, public ObjBase
    {
    };
    class Obje_N : public Node, public ObjBase
    Les Objet instancié devant être utilisés sour la forme Obj_Base (manipulations diverses) ou Node (Stockage et accès en mémoire).
    Le pb est le suivant :
    Accédant aux objets sous la forme Node, il m'est impossible de les transtyper directement en Obj_Base . Si, par contre je connais précisément la classe instanciée par de pb.

    J'ai remarqué que lorsque je transtype un objet de Obj_N vers Node (en vue de le stocker), le pointeur change d'adresse.
    Est-ce un mécanisme normal ?
    Y a-t-il quelque chose qui m'échappe ? (vraisemblablement)
    Enfin quel moyen pour contourner le pb ?

    j'espère avoir été assez clair...

  2. #2
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    http://www.ddj.com/dept/cpp/184402074 ?
    Comment réalises-tu tes casts?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Par défaut
    Genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //instanciation :
    Obj_1* NouvObj=new Obj_1();
     
    // stockage :
    Ma_Classe_de_Stockage->Ajoute((Node*) NouvObj);
     
    //recupération :
    Node* InstNode=Ma_Classe_de_Stockage->Donne(...);
     
    // en vue de manipulations:
    Obj_Base* Obj= (Obj_Base*) InstNode;
     
    Obj->Fonction_Virtuelle_Implémentée_dans_Obj1(); // problème
    par contre l'alternative ci-dessous fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // en vue de manipulations:
    Obj_Base* Obj= (Obj_1*) InstNode;
     
    Obj->Fonction_Virtuelle_Implémentée_dans_Obj1(); // Ok
    Mais beaucoup moins interessente...

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut

    (Pourquoi je ne suis pas surpris par le fait que tu aies des problèmes?)
    Déjà que les casts à la C sont déconseillés en C++, ils sont tout simplement à bannir dès qu'il y a de l'héritage en jeu, plus particulièrement de l'héritage multiple.

    Je t'ai donné de la lecture. C'est la meilleure que je connaisse sur le sujet -- De mémoire, il y avait aussi un bouquin de Lipmann.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Par défaut
    Déjà que les casts à la C sont déconseillés en C++, ils sont tout simplement à bannir dès qu'il y a de l'héritage en jeu, plus particulièrement de l'héritage multiple
    Après un peu de lecture, j'ai tout repris correctement, mais ca n'y change rien...
    Ceci dit, je m'en doutais un peu, car l'article que tu m'as 'prescrit', m'a permis de mieux comprendre les différents mécanismes liés à l'héritage multiple.

    J'ai pour l'instant contourné (ou plutot relégué à plus tard) le problème en faisant dériver Obj_Base depuis Node. Ca ne me plais pas trop mais pour l'instant ça colle...

  6. #6
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Et les "dynamic_cast" n'arrangent pas tes affaires ?

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Par défaut
    Non, lors de la récupération de mon objet il faut nécessairement que je connaisse la classe qui l'a instancié si je veux récuperer un pointeur valide. C'est une limitation sérieuse que me laisse à penser qu'il y a quelque chose qui m'échappe...
    Afin de résoudre le pb si je ne trouve pas d'autre solution je pense stoker le type de l'objet instancié dans la classe Node de sorte qu'une fonction gèrant le cast me fournisse un pointeur valide. Du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Obj_Base* Ma_Fonction_de_Cast(Node* Ptr)
    {
    switch(Ptr->TypeObj)
    {
    case TYPE_OBJ_1:
    return static_cast<Obj_1*> (Ptr);
    case TYPE_OBJ_N:
    return static_cast<Obj_N*> (Ptr);
    }
    return NULL;
    }
    Que pensez-vous de cette approche ?

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par défaut
    Le problème ne vient pas des opérations de transtypage, mais du fait que d'après ton design, un Node n'est pas un ObjBase.
    Si tous les ObjBase peuvent être considérés comme des Node, alors la correction que tu as faite est justifiée.

    Si tu souhaites faire dans le porco, tu peux ajouter une fonction membre à l'interface ObjBase du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual Node * getAsNode() const
    dans laquelle un Node est reconstruit à partir d'un ObjBase ou sauvagement transtypé.

    Si elle est applicable, je milite pour la première solution.

  9. #9
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Puisque c'est le sujet, je ne comprend pas pourquoi le code suivant ne compile pas (GCC 3.2.3 ou VC8). J'ai comme message :
    Source type is not polymorphic.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Base {
    };
     
    class Derived : public Base {
    };
     
    int main(void) {
    	Base *a = new Derived;
    	Derived *p;
     
    	p = dynamic_cast<Derived *>(a);
    	return 0;
    }

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Ta classe de base ne possède aucune fonction virtuelle. Ajoute par exemple le destructeur virtuel, qui sera de toute façon nécessaire si tu utilises le polymorphisme.

  11. #11
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Merci Laurent.

    Donc au risque de paraître lourd, un dynamic_cast est vraiment ce qu'il te faut.

    Exemple :
    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
    class Base1 {
    public:
    	virtual int function1(void);
    };
     
    int Base1::function1(void) {
    	return 1;
    };
     
    class Base2 {
    public:
    	virtual int function2(void);
    };
     
    int Base2::function2(void) {
    	return 2;
    };
     
    class Derived : public Base1, public Base2 {
    };
     
    int main(void) {
    	Base1 *a = new Derived;
    	Base2 *b = dynamic_cast<Base2 *>(a);
    	return 0;
    }

Discussions similaires

  1. composants C++ Builder et héritage multiple
    Par vedrfolnir dans le forum C++Builder
    Réponses: 2
    Dernier message: 12/10/2005, 10h04
  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