Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
328 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  héritage multiple .. pour ou contre ?

 



 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

héritage multiple .. pour ou contre ?

n°1713397
in_your_ph​ion
Posté le 06-04-2008 à 17:32:38  profilanswer
 

Bonjour,
J'aimerai savoir ce que vous pensez de l'héritage multiple en c++, êtes vous plutôt pour ou contre ? J'ai l'impression que beaucoup de langages oo ne le permettent pas ou plus, alors je me demande si c'est quelque chose qui doit être pratiqué ou évité en c++ ?
 
merci d'avance


Message édité par in_your_phion le 06-04-2008 à 17:33:00
mood
Publicité
Posté le 06-04-2008 à 17:32:38  profilanswer
 

n°1713400
Joel F
Real men use unique_ptr
Posté le 06-04-2008 à 17:47:13  profilanswer
 

en général, tu peut t'en passer.
Perso, j'essaye de coller au modèle de java : 1 classe peut héritée d'une classe mère et de X interfaces. En C++, suffit de te dire que classe abstraie = interface ;)

Message cité 1 fois
Message édité par Joel F le 06-04-2008 à 17:47:23

---------------
[ MKM ]
n°1713403
in_your_ph​ion
Posté le 06-04-2008 à 18:01:13  profilanswer
 

Joel F a écrit :

en général, tu peut t'en passer.
Perso, j'essaye de coller au modèle de java : 1 classe peut héritée d'une classe mère et de X interfaces. En C++, suffit de te dire que classe abstraie = interface ;)


 
d'accord, merci. Alors en c++ il n'y a pas de différence entre interface et classe abstraite ? Et quand on parle d'"implémentation" ce sont les classes non abstraites ?
 
merci

n°1713404
Joel F
Real men use unique_ptr
Posté le 06-04-2008 à 18:10:47  profilanswer
 

C'est pas ça.
 
Y a pas de notion d'interface au sens propre en C++.
Juste que leur comportement corresponds à celle des classes abstraites


---------------
[ MKM ]
n°1713411
in_your_ph​ion
Posté le 06-04-2008 à 18:30:36  profilanswer
 

Joel F a écrit :

C'est pas ça.
 
Y a pas de notion d'interface au sens propre en C++.
Juste que leur comportement corresponds à celle des classes abstraites


 
ok, et pour ce qu'on appelle l'"implémentation" ?

n°1713428
jesus_chri​st
votre nouveau dieu
Posté le 06-04-2008 à 19:16:01  profilanswer
 

et bien moi je suis pour, pour et encore pour.
D'ailleurs l'absence d'héritage multiple est un des reproches que je fais au langage D.
 
Déjà à propos des interfaces : ça implique de rendre les méthodes virtuelles alors que c'est rarement utile dans ce cas.
Oui je sais la perte de perf est faible tout ça, mais en C++ il y a un principe important : "Ne paye pas pour ce que tu n'utilise pas". Or imposer des appels virtuels pour contourner l'héritage multiple ne respecte pas ce principe.
 
Joel F parle du Java et je suis d'accord sur ce point, le Java fonctionne différement et est conçu pour faire des appels systématiquement virtuels (même si on peut les désactiver avec static, c'est rarement utilisé). Il est architecturé autour du principe des Interfaces, donc c'est correct de s'en serivir tant que possible.
 
Mais Java et C++ sont différents, et plus que ce que certains croient. J'utilise aussi certains paradigmes du Java qd je code en C++ (les accessors sans surcharge et les méthodes de conversions que je préfère aux opérateurs cast par exemple) mais uniquement qd ça respecte les principes de base du C++.
 
Quand tu veux faire une classe CamionPoubelle en C++, tu peux te contenter de dériver de Camion et de Poubelle. Pas besoin d'une interface ICamion et d'une IPoubelle remplie de méthodes virtuelles pures (appellée méthodes abstraites en java) que tu seras obligé de redéfinir même si t'en as pas besoin.
 
Je ne vois pas le problème à hériter de deux classes en même temps. Certes il y a des cas pourris comme l'héritage en losange (1) et l'héritatge virtuel mais j'ai beaucoup codé en C++ et je ne me souviens pas en avoir eu besoin. Dans des condisions réelles, les deux classes dont on héritent ne rentre jamais en conflit entre elles. Il faut le faire exprès pour avoir des méthodes qui ont le même nom par exemple.
Tant qu'on utilise pas de méthodes venus de certains design pattern comme Visit() ou serialize() il n'y a vraiment aucun problème.
 

Code :
  1. class Camion
  2. {
  3. public :
  4.     Camion( int powerCv );
  5.     void run();
  6.     void stop();
  7. private :
  8.     int m_powerCv;
  9. }
  10. class Poubelle
  11. {
  12. public :
  13.     Poubelle( int capacitySquareMeter );
  14.     void flush();
  15.     void compact();
  16. private :
  17.     int m_capacitySquareMeter;
  18. }
  19. class CamionPoubelle : public Camion, public Poubelle
  20. {
  21. public :
  22.     CamionPoubelle( int power, int capacity ) // je donne un exemple d'apppel des  
  23.     : Camion( power ), Poubelle( capacity  ) {} // constructeurs parents, rien de compliqué
  24. }
  25. // Je veux un Camion-poubelle de 1000cv et 10m² :
  26. CamionPoubelle cp( 1000, 10 );
  27. cp.run(); // avance
  28. cp.stop(); // arrete-toi
  29. cp.compact(); // compacte tes ordures
  30. cp.flush(); // et vidange-les


 
Il est où le problème, elle est où la difficulté ?
En vrai l'héritage multiple c'est surtout chiant à gérer quand on écrit un compilo (les conversions de pointeurs provoquent des décalages...) mais pour le programmeur c'est très utile.
 
Pour répondre à la question de départ, il n'y a aucune fonctionnalité du C++ qui ne doit être éviter, sinon cette fonction ne serait pas dans le langage. C++ n'est pas un langage commercial comme le Java ou Delphi, donc qd il mette une fonctionnalité c'est qu'elle est utile, c'est pas juste pour faire plaisir à leurs actionnaires (2). Et en plus l'héritatge multiple n'entraine aucune perte de perf, contrairement au RTTI ou aux exceptions qu'on peut voiloir éviter dans une optique d'optimisation.
 
Et historiquement je me souviens qu'il y a qlq années on reprochait au C++ d'avoir les templates, soit disant ça servait à rien, c'était compliqué et Java s'en passait bien. Maintenant les templates sont de + en plus utilisés en C++ et le Java a fini par s'en dotter, sous une forme plus simple il est vrai (la généricité). Donc chercher à niveler vers le bas ça ne tient pas longtemps. On finit toujours par avoir besoin de fonctionnalités de + en + avancées.
 
(1) souvent mal traduit par "diamant" (venant de diamond en anglais, qui signifie diamant et losange)
(2) ouais c'est un gros troll contre Sun désolé, par contre pas contre Borland, on ne tire pas sur les ambulances :D

n°1713429
jesus_chri​st
votre nouveau dieu
Posté le 06-04-2008 à 19:18:33  profilanswer
 

merde j'ai oublié les points-virgules derrière les def de classes :D

n°1713438
Joel F
Real men use unique_ptr
Posté le 06-04-2008 à 19:41:51  profilanswer
 

J'ai jamais prophétisé l'abolition de l'héritage multiple.
Moi, perso le camion poubelle, il hérite de camion car C'EST un camion et il implémente IPoubelle car il se COMPORTE COMME une poubelle.

 

après chacun sa sauce :)

 
Citation :


Il faut le faire exprès pour avoir des méthodes qui ont le même nom par exemple.


Dans certains cas de CRTP, ça arrive aussi :s

Message cité 1 fois
Message édité par Joel F le 06-04-2008 à 19:42:43

---------------
[ MKM ]
n°1713447
jesus_chri​st
votre nouveau dieu
Posté le 06-04-2008 à 19:50:07  profilanswer
 

CRTP : skoi cet acronyme ?, ça me dit rien.
 
Avec l'héritage multiple du C++ tu n'as justement pas besoin de te demander si c' "est-une" poubelle ou si ça "implémente" (se comporte comme) une poubelle, puisque les deux reviennent au même niveau code.
 
Par contre dans un contexte Java, même avec l'héritage multiple possible, j'approuverais ton utilisation d'une interface pour Poubelle. Ca serait + élégant et pas plus couteux en perfs.
 
En C++ par convention le "is-a" est utilisé comme premier héritage, et le "implements" comme héritage secondaire. Ca permet aussi de pouvoir convertir en dur un pointeur de CamionPoubelle en Camion, mais pas en Poubelle. Mais c'est juste une convention.

n°1713450
Joel F
Real men use unique_ptr
Posté le 06-04-2008 à 19:57:29  profilanswer
 

jesus_christ a écrit :

CRTP : skoi cet acronyme ?, ça me dit rien.


Curiously Recursive Template Pattern
 

jesus_christ a écrit :


Avec l'héritage multiple du C++ tu n'as justement pas besoin de te demander si c' "est-une" poubelle ou si ça "implémente" (se comporte comme) une poubelle, puisque les deux reviennent au même niveau code.
Par contre dans un contexte Java, même avec l'héritage multiple possible, j'approuverais ton utilisation d'une interface pour Poubelle. Ca serait + élégant et pas plus couteux en perfs.
 
En C++ par convention le "is-a" est utilisé comme premier héritage, et le "implements" comme héritage secondaire. Ca permet aussi de pouvoir convertir en dur un pointeur de CamionPoubelle en Camion, mais pas en Poubelle. Mais c'est juste une convention.


 
Disons que j'aime bien faire ce distingo, ca aide à garder séparer les classes qui ont tendances à êtres concretes et les autres.
Encore une fois, ca n'engage que moi.


---------------
[ MKM ]
mood
Publicité
Posté le 06-04-2008 à 19:57:29  profilanswer
 

n°1713453
MagicBuzz
Posté le 06-04-2008 à 20:00:11  profilanswer
 

"Ca permet aussi de pouvoir convertir en dur un pointeur de CamionPoubelle en Camion, mais pas en Poubelle."
 
Je trouve ça un peu con :/
 
Moi qui croyait que justement l'héritage multiple permettait de faire ça...
Du coup je préfère les interfaces au moins on peut instancier un objet selon l'interface désirée, sans ce soucier de qui fait quoi à la base dans l'héritage.
A moins que j'aie mal compris la phrase ?


Message édité par MagicBuzz le 06-04-2008 à 20:02:29
n°1713455
jesus_chri​st
votre nouveau dieu
Posté le 06-04-2008 à 20:02:45  profilanswer
 

Curiously Recursive Template Pattern
 
Je connais ça, mais pas l'acronyme ;)
Ca arriverait donc si les deux classes dont on hérite utilisent ce CRTP ? Oui en effet, c'est une forme d'héritage de noms en losange.

n°1713460
Joel F
Real men use unique_ptr
Posté le 06-04-2008 à 20:05:49  profilanswer
 

jesus_christ a écrit :


Ca arriverait donc si les deux classes dont on hérite utilisent ce CRTP ? Oui en effet, c'est une forme d'héritage de noms en losange.


 
ouais mais bon, pour en faire comme pas possible, ca a du m'arriver 2 fois quoi  [:absolutelykaveh]


---------------
[ MKM ]
n°1713462
jesus_chri​st
votre nouveau dieu
Posté le 06-04-2008 à 20:09:14  profilanswer
 

qd je parle de "en dur" c'est du genre :
 

Code :
  1. CamionPoubelle cp;
  2. void* ptr = &cp;
  3. ...
  4. Camion* c = (Camion*)ptr; // ça marche
  5. Poubelle* p = (Poubelle*)ptr; // ça marche pas
  6. Poubelle* p2 = &cp; // ça marche, et c'est surement ça que tu veux faire.


 
Pourquoi j'utilise un void* ?
Dans le cas d'une utilisation d'un langage externe (perso j'utilise souvent du LUA) pour lequel la donnée est un pointeur abstrait, le void* est inévitable. C'est pareil pour du code API Win32 :
 

Code :
  1. HWND CreateWindowEx(          DWORD dwExStyle,
  2.     LPCTSTR lpClassName,
  3.     LPCTSTR lpWindowName,
  4.     DWORD dwStyle,
  5.     int x,
  6.     int y,
  7.     int nWidth,
  8.     int nHeight,
  9.     HWND hWndParent,
  10.     HMENU hMenu,
  11.     HINSTANCE hInstance,
  12.     LPVOID lpParam // <- attention si hériatage multiple
  13. );


 
edit : je précise qu'avec une Interface, ça ne marche pas mieux qd on utilise un void*, ça a même tendance à être pire.


Message édité par jesus_christ le 06-04-2008 à 20:17:27
n°1713488
MagicBuzz
Posté le 06-04-2008 à 21:37:16  profilanswer
 

Ah ok, me voilà rassuré, sur le coup j'ai eu peur ;)

n°1713523
El muchach​o
Comfortably Numb
Posté le 06-04-2008 à 23:28:06  profilanswer
 

Joel F a écrit :

J'ai jamais prophétisé l'abolition de l'héritage multiple.
Moi, perso le camion poubelle, il hérite de camion car C'EST un camion et il implémente IPoubelle car il se COMPORTE COMME une poubelle.  


En même temps, y'a des voitures qui sont des poubelles, mais c'est une autre histoire. :o

n°1713529
in_your_ph​ion
Posté le 07-04-2008 à 00:15:11  profilanswer
 

Salut,
merci beaucoup pour toutes ces explications très poussées .... :) Je viens de m'entrainer sur un exo d'héritage en losange, c'est mal ? (Je vais poster mon exo dans un autre thread, ce sera mieux)
 
@Jesus :
 

Code :
  1. CamionPoubelle cp;
  2. void* ptr = &cp;
  3. ...
  4. Camion* c = (Camion*)ptr; // ça marche
  5. Poubelle* p = (Poubelle*)ptr; // ça marche pas
  6. Poubelle* p2 = &cp; // ça marche, et c'est surement ça que tu veux faire.


 
pourrais tu m'expliquer pourquoi  Poubelle* p = (Poubelle*)ptr; ne marche pas ? est-ce par rapport au fait que dans l'héritage il y a d'abord "public Camion" et ensuite "public Poubelle" ?
 
merci encore

n°1713560
jesus_chri​st
votre nouveau dieu
Posté le 07-04-2008 à 08:17:04  profilanswer
 

oui.
 
Dans CamionPoubelle, la partie Camion se trouve au début, donc l'adresse de la partie Camion de la structure est la même que celle de CamionPoubelle.
Par contre la partie Poubelle se trouve + loin, et si on prend l'adresse de la partie poubelle de la structure, il faut décaler le pointeur.
 


addr CamionPoubelle  
|
+-------------------+
|   CamionPoubelle  |
+-------------------+
 
est en interne :
 
+--------+----------+
| Camion | Poubelle |
+--------+----------+
|        |
addr     addr
Camion   Poubelle

Message cité 1 fois
Message édité par jesus_christ le 07-04-2008 à 08:17:15
n°1713574
Joel F
Real men use unique_ptr
Posté le 07-04-2008 à 09:03:27  profilanswer
 

El muchacho a écrit :


En même temps, y'a des voitures qui sont des poubelles, mais c'est une autre histoire. :o


 
lol ^^ en effet  [:spyer]


---------------
[ MKM ]
n°1713604
ElDesdicha​do
Posté le 07-04-2008 à 10:37:47  profilanswer
 

Bon au risque de me faire fusillé, j'ai développé un moteur de calcul qui utilise de l'héritage multiple et des losanges. Mes collègues bien plus forts que moi en C++ ne m'ont pas trop crié dessus, donc je vais expliquer quel était le problème de départ et ensuite si vous avez des idées pour faire mieux je suis évidemment preneur.  
Mon problème est le suivant, je veux créer un produit qui a des caractéristique, et si c'est possible j'aimerai créer son type au moment de la compilation, on va dire que les caractéristiques sont Call,Barrière,Swap,Constant, etc... Ensuite j'ai plein de produit qui peuvent combiner une ou plusieurs de ses caractéristiques voire même plusieurs barrières, qui plus est une notion d'ordre est nécessaire parce que lorsque je dit "combiner" en fait je parle de composition (en terme de fonction). Ensuite les propriétés peuvent dériver entre elles, genre Putable dérive de Callable. Donc j'ai un beau merdier, et je suis hyper fainéant je veux éviter de réécrire plein de classes dérivées genre DoubleBarrière dérivant de Barrière. Le seul avantage c'est que mes propriétés partage le même squelette de base et ne comporte que très peu de méthodes. Donc j'ai pensé (out of the box) au type de structure suivant:
 
Toutes mes propriétes (que j'appelle module) dérivent d'une seule classe de base et comporte 2-3 méthodes, là je peux dériver entre elles et j'ai toute une famille à ma disposition. En plus je les définit avec un argument template <int> dummy pour pouvoir combiner par la suite les même modules (je sais c'est pas beaux mais ca a aussi des côtés intéressants).
Enfin je décide de créer une class qui hérite virtuellement de deux modules pour les mélanger, là je décrit les relations d'ordres (qui on va créer en premier), et la composition fonctionelle, la classe ressemble à ca:
 

Code :
  1. template<class X, class Y>
  2. class PDEMix : virtual public X, virtual public Y, public with_type_traits<PDEMix<X,Y> >
  3. {
  4. public:
  5. using with_type_traits<PDEMix<X,Y> >::sp;
  6. using with_type_traits<PDEMix<X,Y> >::const_sp;
  7. using X::Calc;
  8. using X::setDim;
  9. using X::setPDEParameters;
  10. PDEMix(int BucketedGreeks=0, int NumStocks=1, int bOneCurve=1,CalibrationSet * calibraSet=NULL) : X(BucketedGreeks,NumStocks, bOneCurve, calibraSet),
  11.  Y(BucketedGreeks,NumStocks, bOneCurve, calibraSet)
  12. {}
  13. virtual ~PDEMix()
  14. {}
  15. /// Creates the Properties.
  16. inline std::vector<EQPDEProperty_Base::sp> createProperties()
  17. {
  18.  std::vector<EQPDEProperty_Base::sp> vect_X = X::createProperties();
  19.  std::vector<EQPDEProperty_Base::sp> vect_Y = Y::createProperties();
  20.  std::copy(vect_Y.begin(),vect_Y.end(),back_inserter(vect_X));
  21.  m_vspProperties.assign(vect_X.begin(), vect_X.end());
  22.  return m_vspProperties;
  23. }
  24. /// CalcValue.
  25. inline virtual double CalcValue()
  26. {
  27.  return PDESolve<typename PDEMix<X,Y> >();
  28. }
  29. /// PDESolve.
  30. template<class Module> double PDESolve()
  31. {
  32.            ...
  33. }
  34. private:
  35. };


 
Bon ensuite pour donner un exemple lorsque je veux créer un produit qui correspond à une Bairrière sur un Call je fait:

Code :
  1. PDEMix<PDECallPut<0>,PDEBarrier<0> > monProduit;


Lorsque je veux créer deux barrières sur un call:

Code :
  1. PDEMix<PDEMix<PDECallPut<0>,PDEBarrier<0> >, PDEBarrier<1> > monProduit;


etc... J'ai une récurrence vachement flexible pour prototyper des produits, j'aime bien c'est cool, m'enfin ca reste du losange... Sinon lorsque j'ai une famille de propriétés qui vont partager des variables similaires et bien je peux les définir statique par famille, genre une famille de Callable 0 et 1 i.e. Callable<0> et Callable<1>. Jusqu'à présent l'expérience nous montre que malgré un design alambiqué le prototypage de produit est devenu très rapide (je suis dans un environnement ou quelques heures peuvent faire la différence), et c'est assez efficaces en terme de temps de calcul. Ensuite c'est une solution à mon problème particulier, et je suis sûr que l'on peut faire mieux (d'ailleurs j'attends les suggestions).
 

n°1713608
Joel F
Real men use unique_ptr
Posté le 07-04-2008 à 10:47:05  profilanswer
 

Encore une fois : j'ai rien contre l'héritage multiple, juste que si je peut m'en passer, je m'en passe. ^^
 
@ElDesdichado : ton truc c'est purement 'industriel' ou y a des papiers dessus ? Je cherche des exemples de ce types d'idiomes de prog hors HPC.


---------------
[ MKM ]
n°1713613
ElDesdicha​do
Posté le 07-04-2008 à 10:54:32  profilanswer
 

Non purement industriel (enfin adaptés à nos besoin). M'enfin je dirai plutôt purement amateur, dans la mesure où c'est de bibi i.e. avec mes mimines et mes idées foireuses, donc si il y a des articles je suis preneur. Pour ce qui est du code en entier, je peux pas vraiment le poster, ils me versent un salaire donc... Quant à savoir si c'est bien fait ou d'un quelconque intérêt je précise que je suis mathématicien et pas un expert du C++ (heureusement j'ai un collègues qui s'y connaît pas mal). Quoiqu'il en soit on l'utilise en production pour chiffrer autre chose que des boîtes à savon ;)
 

n°1713636
Joel F
Real men use unique_ptr
Posté le 07-04-2008 à 11:09:26  profilanswer
 

c'était exactement ce genre d'infos que je voulais (les boites à savons ;) )


---------------
[ MKM ]
n°1713642
ElDesdicha​do
Posté le 07-04-2008 à 11:18:52  profilanswer
 

M'enfin il était pas difficile de deviner de quelles boîtes à savon je parle. De toute manière je t'ai PM.

n°1713756
in_your_ph​ion
Posté le 07-04-2008 à 13:48:10  profilanswer
 

jesus_christ a écrit :

oui.
 
Dans CamionPoubelle, la partie Camion se trouve au début, donc l'adresse de la partie Camion de la structure est la même que celle de CamionPoubelle.
Par contre la partie Poubelle se trouve + loin, et si on prend l'adresse de la partie poubelle de la structure, il faut décaler le pointeur.
 


addr CamionPoubelle  
|
+-------------------+
|   CamionPoubelle  |
+-------------------+
 
est en interne :
 
+--------+----------+
| Camion | Poubelle |
+--------+----------+
|        |
addr     addr
Camion   Poubelle



 
d'accord ! c'est vrai que c'est logique en fait!
 
merci :)

n°1722950
in_your_ph​ion
Posté le 23-04-2008 à 16:19:26  profilanswer
 

in_your_phion a écrit :


@Jesus :
 

Code :
  1. CamionPoubelle cp;
  2. void* ptr = &cp;
  3. ...
  4. Camion* c = (Camion*)ptr; // ça marche
  5. Poubelle* p = (Poubelle*)ptr; // ça marche pas
  6. Poubelle* p2 = &cp; // ça marche, et c'est surement ça que tu veux faire.




 
up,
 
j'ai essayé ça et ça marche dans les trois cas ... kesako ??

n°1723149
jesus_chri​st
votre nouveau dieu
Posté le 23-04-2008 à 20:09:57  profilanswer
 

t'es bien passé par un void* ?
Une de tes deux classes de base n'est pas vide ?
T'as essayé de compiler, ou vraiment d'éxécuter ?
 
Parce que avec 2 classes non vides et en passant par un voird*, c'est juste pas possible que ça marche !

n°1723256
Aiua
PSN : Aiua / GT : Aiua42
Posté le 24-04-2008 à 00:46:46  profilanswer
 

de toutes façons utiliser le cast C (Type*) en C++, c'est mal :o

 

et sinon l'héritage multiple c'est très pratique et ça permet de bien mieux factoriser le code que l'interfaçage à la java :o


Message édité par Aiua le 24-04-2008 à 00:48:48

---------------
"The pen is mightier than the sword if the sword is very short, and the pen is very sharp." TP. Mes Jeux. Mes Ventes. Groupe HFR sur PlayFire.
n°1723285
Joel F
Real men use unique_ptr
Posté le 24-04-2008 à 08:11:40  profilanswer
 

ou pas ! :o
et
ou pas :o !


---------------
[ MKM ]
n°1723637
in_your_ph​ion
Posté le 24-04-2008 à 14:25:06  profilanswer
 

jesus_christ a écrit :

t'es bien passé par un void* ?
Une de tes deux classes de base n'est pas vide ?
T'as essayé de compiler, ou vraiment d'éxécuter ?

 

Parce que avec 2 classes non vides et en passant par un voird*, c'est juste pas possible que ça marche !

 

salut,

 

j'ai essayé ça mais peut être que c'est pas bon alors comme ça marche  :pt1cable: :

 
Code :
  1. class A {
  2. public:
  3.  A() { cout  << "construction de A" << endl; }
  4.  virtual ~A() { cout << "destruction de A" << endl; }
  5.  virtual void print() { cout << "A says hello" << endl; }
  6. };
  7. class B {
  8. public:
  9.  B() { cout  << "construction de B" << endl; }
  10.  virtual ~B() { cout << "destruction de B" << endl; }
  11.  virtual void print() { cout << "B says hello" << endl; }
  12. };
  13. class C : public A, public B {
  14. public:
  15.  C() { cout  << "construction de C" << endl; }
  16.  ~C() { cout << "destruction de C" << endl; }
  17.  void print() { cout << "C says hello" << endl; }
  18. };
  19. int main() {
  20. C c;
  21. void * ptr = &c;
  22. A * a = (A*)ptr; //ça devrait marcher
  23. B * b = (B*)ptr; //ça devrait pas marcher ?
  24. system("pause" );
  25. return 0;
  26. }


Message édité par in_your_phion le 24-04-2008 à 14:26:46
n°1723846
Aiua
PSN : Aiua / GT : Aiua42
Posté le 24-04-2008 à 16:06:24  profilanswer
 

Joel F a écrit :

ou pas ! :o
et
ou pas :o !


pour le premier je me sens obligé d'insister, en plus d'être illisible, ça masque totalement le type de cast effectué
 
pour le 2e, y a la composition pour contrebalancer, mais c'est chiant :o


---------------
"The pen is mightier than the sword if the sword is very short, and the pen is very sharp." TP. Mes Jeux. Mes Ventes. Groupe HFR sur PlayFire.
n°1723885
Joel F
Real men use unique_ptr
Posté le 24-04-2008 à 16:34:00  profilanswer
 

pour le C-style cast, je t'accorde que un bon vieux xxx_cast<> a plus de charme. Malheureusement, dés fois, ca fait trop ce que tu veut :/


---------------
[ MKM ]
n°1723897
Joel F
Real men use unique_ptr
Posté le 24-04-2008 à 16:44:28  profilanswer
 


 
Non c'est bon :o


---------------
[ MKM ]
n°1723900
in_your_ph​ion
Posté le 24-04-2008 à 16:47:00  profilanswer
 

et sinon par rapport à ma question ... plz ....
 
 :hello:

n°1724080
El muchach​o
Comfortably Numb
Posté le 24-04-2008 à 23:58:34  profilanswer
 

Joel F a écrit :


 
lol ^^ en effet  [:spyer]


D'ailleurs ne dit-on pas parfois : "fait chier, j'ai encore hérité d'une poubelle :o" ?
 
Nouvel exemple d'héritage dont on voudrait bien se passer. :o

n°1724718
jesus_chri​st
votre nouveau dieu
Posté le 25-04-2008 à 21:15:50  profilanswer
 

Code :
  1. class A {
  2. public:
  3.  A() { cout  << "construction de A" << endl; }
  4.  virtual ~A() { cout << "destruction de A" << endl; }
  5.  virtual void print() { cout << "A says hello" << endl; }
  6. };
  7. class B {
  8. public:
  9.  B() { cout  << "construction de B" << endl; }
  10.  virtual ~B() { cout << "destruction de B" << endl; }
  11.  virtual void print() { cout << "B says hello" << endl; }
  12. };
  13. class C : public A, public B {
  14. public:
  15.  C() { cout  << "construction de C" << endl; }
  16.  ~C() { cout << "destruction de C" << endl; }
  17.  void print() { cout << "C says hello" << endl; }
  18. };
  19. int main() {
  20. C c;
  21. void * ptr = &c;
  22. A * a = (A*)ptr; //ça devrait marcher
  23. B * b = (B*)ptr; //ça devrait pas marcher ?
  24. // jusque là tout va bien...
  25. b->print(); // CRASH !!
  26. system("pause" );
  27. return 0;
  28. }

n°1724720
jesus_chri​st
votre nouveau dieu
Posté le 25-04-2008 à 21:18:05  profilanswer
 

system("pause" ); <- pas bien, pas portable et si tu veux arréter ton prog à la fin, mets un breakpoint ou passe par un .bat/.sh
 
ici avec un peu de malchance ça va pas cracher car les deux classes sont de taille vide sauf pour le vtable-pointeur. Donc si ça se trouve ça va pas planter et afficher "A says hello".

n°1724746
IrmatDen
Posté le 25-04-2008 à 22:01:16  profilanswer
 

jesus_christ a écrit :

system("pause" ); <- pas bien, pas portable et si tu veux arréter ton prog à la fin, mets un breakpoint ou passe par un .bat/.sh


cin.get() ? :whistle:  
</contribution à 2 balles>

n°1724750
jesus_chri​st
votre nouveau dieu
Posté le 25-04-2008 à 22:06:29  profilanswer
 

getchar() ou cin.get à la rigueur...
 
mais bon débugger avec des getchar() et des printf()... il y a de très bons debugger gratuits en plus.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  héritage multiple .. pour ou contre ?

 

Sujets relatifs
[Javascript] héritage entre classe dans des fichiers différentsquestion héritage CSS
petite question sur l'héritage et les castquestion de débutant, casts & héritage
[MySQL] Héritage ?Qui veut un massage contre une base de donnée ?
TListBox à choix multipleMysql - LEFT JOIN Multiple sur une même table
Ce principe est-il efficace contre les bots ?héritage et méthodes virtuelles ?
Plus de sujets relatifs à : héritage multiple .. pour ou contre ?


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR