begin process at 2012 05 29 17:27:31
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

Problème d'héritage multiple


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Problème d'héritage multiple

mercredi 19 avril 2006 à 22:35:00 | Problème d'héritage multiple

Aquarian

    Bonjour,

Voici un morceau de code sur lequel j'ai un problème, en fait il se compile bien sous Visual Studio .NET 2003 ou sous Dev-cpp, mais il ne fait pas vraiment ce que je souhaiterai.

#include <iostream>
using namespace std;

class A {
public:
    A(int a) :_a(a) {}
    void write() {cout << " A : " << _a << endl; }

protected:
    int _a;
};


class BInterface {
      public:
          void writeB() {cout << " B : " << _valeurB << endl; }
      protected:
        BInterface() : _valeurB(1){}
      private :
         int _valeurB;
};


class B : public A, public BInterface {
      public:
        B(int a): A(a), BInterface() {}
};

class CInterface {
      public:
        void writeC() {cout << " C : " << _valeurC << endl; }
      protected:
        CInterface() : _valeurC(2) {}
      private :
        int _valeurC;
};

class C : public A, public CInterface {
      public:
        C(int a) : A(a), CInterface() {}
};


class D : public A, public BInterface, public CInterface {
      public:
        D(int a) : A(a), BInterface(), CInterface() {}
};

int main(int argc, char* argv[])
{
    A* ptr = new D(8);

    ptr -> write();
    ((B*)ptr) -> writeB();
    ((C*)ptr) -> writeC();

    cin.get();
}

>> SORTIE DU PROGRAMME :
A : 8
B : 1
C : 1                        // ??? Tiens donc ???

Donc ce système marche (compile) mais n'est pas correct, j'ai l'impression (je me trompe peut-être) que les instructions
    ((B*)ptr) -> writeB();
    ((C*)ptr) -> writeC();
se font très mal, elles se baseraient sur l'organisation mémoire des classes B et C (normal vu le cast) et non sur celle de D.

J'aimerai obtenir le schéma d'héritage suivant :
     A        
    /   \          En fait je sais qu'il faudrait déclarer class B : public virtual A mais dans ce cas,
  /       \        je ne peux pas convertir directement un pointeur de A en un pointeur vers B
B        C      ou C sauf en utilisant un dynamic_cast. Or dans ma fonction, je connais le
  \      /         le type du pointeur sur A, je sais que c'est un pointeur sur B ou D. Ca me
    \  /           ça me semble donc contraignant d'utiliser un dynamic cast qui va faire le
     D           branchement sur la bonne fonction durant l'exécution...

En gros mon entête de fonction est le suivant :

void maFonction (A* ptr) {
// Ici je sais que lorsque j'ai appelé cette fonction A est un pointeur sur un B ou un D
    ((B*)ptr) -> writeB();  // Ligne qui ne marche pas si j'ai un héritage virtuel
}

Mon essai précédent était pour essayer de palier au problème de classes de bases virtuelles mais du coup je me retrouve coincé au niveau de ma fonction de traitement...

Est-ce que quelqu'un pourrait m'aider et me donner une piste pour que je puisse réorganiser l'ensemble de mes fonctions? Et au pire dois-je absoluement faire un dynamic_cast ?

_________
Aquarian
jeudi 20 avril 2006 à 10:43:42 | Re : Problème d'héritage multiple

Aquarian

    Bonjour à tous,

Finalement j'ai résolu mon problème non sans évité pas mal de warning à la compilation mais qui est une solution propre à mon problème. Voici le code :

class A {
public:
    A(int a) :_a(a) {}
    void write() {cout << " A : " << _a << endl; }
    virtual void writeB() {}
    virtual void writeC() {}

protected:
    int _a;
};

class B : public virtual A {
      public:
          B(int a) : A(a), _valeurB(1) {}
          void writeB() {cout << " B : " << _valeurB << endl; }

    protected:
          B() : _valeurB(1);
     private :
         int _valeurB;
};

class C : public virtual A {
      public:
          C(int a) : A(a), _valeurC(2) {}
          void writeC() {cout << " C : " << _valeurC << endl; }
      protected:
        C() : _valeurC(2) {}
      private :
        int _valeurC;
};

class D : public A, public B {
    public:
       D(int a) : A(a), B(), C() {}
};

int main(int argc, char* argv[])
{
    A* ptr = new D(8);

    ptr -> write();            // En fait pas besoin de cast pour
    ptr -> writeB();         // faire ces différents appels c'est pour
    ptr -> writeC();         // ça que je me suis planté, je voulais
                                     // faire un cast avant de lancer la fonction
    cin.get();
}

Ce code, comme je le disais plus haut provoque pas mal de warning (surtout si writeB et writeC prennent des paramètres, on a des avertissements comme quoi les variables passées en paramètre ne sont pas utilisées). Les warning en plus sont sur le changement de fonction appelée suivant la classe (rien de vraiment problématique, mais je ne sais pas si on peut les éviter).

Il me reste tout de même une question :
Dans le livre de Stroustrup (chap. 15.2.5.1), on peut mettre les deux fonctions writeB et writeC en virtuelles pures or cela ne peut marcher si on ne définit pas les deux fonctions dans chacune des classes héritantes ? Ou je me trompe et j'ai encore des erreurs dans mon code ? J'ai essayé mais à chaque fois il me dit que je n'ai pas le droit d'instancier la classe B ou la classe C car la classe est virtuelle....

_________
Aquarian


Cette discussion est classée dans : public, int, class, ptr, binterface


Répondre à ce message

Sujets en rapport avec ce message

class A:public int ??? [ par foxz ] J'ai besoin de faire ca : class A:public int{}; mais ca ne marche pas. (ni avec float) En fait, je veux cree une class ressemblant a un int mais j'a [client pop3]Exception non gérée [ par electron159 ] Bonjour,  je suis sous visual studio, mode console. j'ai essayé d'adapter un client pop3 linux pour qu'il tourne sous windows. Mais, j'ai une exceptio Question syntaxe C++ [ par max12 ] Bonjour,J'ai c'est la première fois que j'utilise les template en C++ et j'ai un soucis, c'est surement quelque chose de très simple au point que vous heritage [debutant] [ par yanne1985 ] salut j'ai un ptit probleme avec l'heritageclass Point { protected: int X;intY; public : int X ; int Y ; Point (int X=0) { this constructeur herité implicite [ par Guillemouze ] salut a tous, j'ai une question toute bete : est il possible d'appeler implicitement un constructeur d'une class mere?j'ai 3 niveaux de classes; et je affichache d'un document en c [ par godar8 ] j'ai fait un programe  d'editeur de texte en  c  pour cretion document , ajout , supprimer etcmais j'ai un petit  mon document ne s'affiche  pas pour Creation de class en C++ [ par js1000 ] Bonjour a tous !Je suis novice en C++ et je suis en train d'apprende les bases. J'ai donc une question a vous posez :Je veux ecrire une classe Matrice gestion de memoire [ par gyzmo1 ] Salut à tous, j ai un problème de fuite de mémoire, minime mais suffisamment important pour faire planter mon programme lorsque celui ci tourne des he [debutant]Operation de chaine encore :s [ par firemax ] Bonjour Certain reconaitrons ce code (surtout vecchio56) mais voila ca marche toujours pas et je ne comprend pas :'( Please helllppp Code : #in /* * Classe CWindow */ template <typename T> class CWindow: public CSingleton<T> { private: protected: GtkWidget* pwindow; public: CWindow(); void init(void); Warning de compilation - méthodes virtuelles [ par neodelphi ] Bonjour tout le monde, Je suis en train de coder une classe et j'ai besoin de définir une méthode virtuelle pure. Ma première question est quelle est


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,468 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales