[c++] Liste Chainée sans STL ?

Liste Chainée sans STL ? [c++] - C++ - Programmation

Marsh Posté le 11-02-2003 à 17:04:22    

Bonjour,
 
c'est plus un problème de modélisation que de C++ mais bon, vu que c'est en C++ que ca me pose problème...
 
J'ai deux classes: Brique et Mur (pour simplifier).
Un mur etant composé de briques, j'ai fait dériver Brique de Mur (relation de composition). J'ai donc ca:
 
class Brique{}
 
et
 
class Mur : public Brique {} //contient un tableau de Brique
 
Jusuqe là tout marche nickel pour le polymorphisme dynamique et tout.
Maintenant, il se trouve que j'ai besoin de stocker dans une liste chainée des éléments des 2 types (on ne le sait bien sûr qu'a l'execution).
Je ne peux pas utiliser la STL (donc pas de vector ou de templates). Oui c'est con, mais c'est comme ca.
 
J'ai pensé à plusieurs solutions, mais aucune ne me semble justes, aussi je sollicite l'avis d'un oeil extérieur :)
 
1ere Solution:
 
Ma liste est composé de 2 membres (en plus des next et prev pour la parcourir)  et d'un type:
Mur *ptrMur;
Brique *ptrBrique;
int intType;    //contient 0 (la brique) ou 1 (le mur) suivant lequel est contenu dans le maillon
 
Donc là je pense que ca marche, je peux stocker n'importe lequel des 2 types dans un maillon, mais  on c'est pas tres beau niveau modélisation : pas de polymorphisme dynamique(si j'ai un 3eme type a rajouter par exemple, je suis obliger de l'ajouter a la main dans le code, c'est pas tres evolutif.)
 
2eme Solution:
J'ai un seul membre Brique* ou Mur*
 
Problème: ca devrait utiliser le polymorphisme dynamique (puisque apres Mur descend de Brique). En pratique je n'arrive a stocker que l'un ou l'autre des types (celui qui est membre en fait).
 
3eme solution:
On reprend la 2eme solution mais en transformant la Brique* en Mur* de 1 brique avant d'insérer dans la chaine. J'ai pas testé mais ca doit marcher.
Inconvénient: c'est lourd et moche.
 
Je pense que la 2eme solution est la mieux, mais je n'arrive pas a l'implémenter correctement. Suis-je dans l'erreur ?
 
D'avance merci :)

Reply

Marsh Posté le 11-02-2003 à 17:04:22   

Reply

Marsh Posté le 11-02-2003 à 17:09:19    

A la base, le fait de dériver Mur de Brique, je trouve cela très moyen, car a priori tu ne manipules pas un mur comme tu manipules une brique (c'est le principe de l'héritage).
 
Par contre, rien ne t'empêche de définir une super-classe "ElementDeConstruction" dont hériterait à la fois Mur et Brique. Dans cette classe (éventuellement abstraite), tu peux déclarer voire définir le comportement commun de Mur et Brique.  Et ta liste chaînée manipulerait alors des pointeurs sur ElementDeConstruction.

Reply

Marsh Posté le 11-02-2003 à 17:28:24    

BifaceMcLeOD a écrit :

A la base, le fait de dériver Mur de Brique, je trouve cela très moyen, car a priori tu ne manipules pas un mur comme tu manipules une brique (c'est le principe de l'héritage).
 
Pourtant l'héritage peut etre aussi vue comme relation d'agrégation ou de composition, non ?
 
Par contre, rien ne t'empêche de définir une super-classe "ElementDeConstruction" dont hériterait à la fois Mur et Brique. Dans cette classe (éventuellement abstraite), tu peux déclarer voire définir le comportement commun de Mur et Brique.  Et ta liste chaînée manipulerait alors des pointeurs sur ElementDeConstruction.
 
J'y pensais aussi... je vais essayer comme ca, merci

Reply

Marsh Posté le 11-02-2003 à 17:33:15    

Citation :


Pourtant l'héritage peut etre aussi vue comme relation d'agrégation ou de composition, non ?


 
Justement pas, l'agregation ou la composition c'est (pour faire simple) quand un object contient un autre object en temps que membre  
exemple :
 
Voiture est composee de 4 roues et un volant
 

Code :
  1. class Voiture
  2. {
  3.    public:
  4.    Roue roue[4];
  5.    Volant volant;
  6. }


 
Ici il y a aucune raison pour que roue derive de voiture ou inversement, le comportement des deux classes etant complement different.


Message édité par fykman le 11-02-2003 à 17:33:43
Reply

Marsh Posté le 11-02-2003 à 17:34:35    

Tamahome a écrit :

Pourtant l'héritage peut etre aussi vue comme relation d'agrégation ou de composition, non ?


Même si le langage le permet, je te le déconseille plus que fortement, et réserver l'héritage pour la spécialisation et la généralisation. Si tu veux faire de l'aggrégation, déclare un attribut du type agrégé dans la classe aggrégatrice.
Sinon, le programme devient vite difficile à comprendre (la meilleure preuve, c'est que toi même tu as du mal), et tu peux même te retrouver avec des bugs, parce que la relation d'héritage autorise des opérations qui n'ont pas de sens.

Reply

Marsh Posté le 11-02-2003 à 17:45:39    

Comme on dit souvent : l'héritage est la relation la plus forte qui peut exister entre 2 classes après les "friend".
 
Pour choisir la bonne relation à utiliser, il faut toujours choisir la relation la plus faible qui résolve ton problème.

Reply

Marsh Posté le 11-02-2003 à 18:11:03    

fykman a écrit :

Citation :


Pourtant l'héritage peut etre aussi vue comme relation d'agrégation ou de composition, non ?


 
Justement pas, l'agregation ou la composition c'est (pour faire simple) quand un object contient un autre object en temps que membre  
exemple :
 
Voiture est composee de 4 roues et un volant
 

Code :
  1. class Voiture
  2. {
  3.    public:
  4.    Roue roue[4];
  5.    Volant volant;
  6. }


 
Ici il y a aucune raison pour que roue derive de voiture ou inversement, le comportement des deux classes etant complement different.


 
Petit bémol: J'ai pris cet exemple (brique/mur de briques) pour montrer la composition. Dans mon programme, ces 2 classes ont des comportement tres tres similaires, d'ou ma relation d'heritage.

Reply

Marsh Posté le 12-02-2003 à 06:52:30    

1ere Solution: Ma liste est composé de ... et d'un type:
À fuir.
 
2eme Solution: J'ai un seul membre Brique* ou Mur*
Je comprends pas trop.
 
3eme solution: On reprend la 2eme solution mais en transformant la Brique* en Mur* de 1 brique avant d'insérer dans la chaine.
Tu perd l'identité de la brique, c'est pas terrible.
 
 
Une possibilité est de faire un héritage privé (est implémenté en terme de).
Réutilisation des méthodes, mais adieu le polymorphisme externe.
 
La classe de base abstraite me semble la meilleure solution.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 15-02-2003 à 18:29:53    

Bon pour simplifier :
 
je cherche un exemple de liste chainée (sans STL: ni vector ni template) en C++ (pas en C) permettant de chainer des objets héterogenes (par exemple 2 classes A et B (B dérivant de A)).
 
Si quelqu'un a ca en stock ca m'aiderait bien (google me donne que du STL).
 
genre :
 

Code :
  1. class A {...}
  2. class B : public A {...}


 
et une classe de liste chainée
 

Code :
  1. class ListeChainee
  2. {
  3.     ...
  4.     public:
  5.         void add(...);
  6. }


 

Code :
  1. int main (void)
  2. {
  3.     ListeChainee *LC = new ListeChainee();
  4.     A a;
  5.     B b;
  6.     LC.add (a);
  7.     LC.add(b);
  8. }


 
un truc dans le genre ca serait parfait. J'ai bien essayé de toutes les facons possibles, mais je finirai suerment a l'asile  [:totoz] avant d'avoir trouver la moindre solution correcte (sans bidouille).

Reply

Marsh Posté le 15-02-2003 à 18:44:41    

spa possible en C++. soit tu passes par un template, sois par des pointeurs génériques, soit par une lsite de boost::any<T>

Reply

Marsh Posté le 15-02-2003 à 18:44:41   

Reply

Marsh Posté le 15-02-2003 à 19:31:50    

Tamahome a écrit :

Petit bémol: J'ai pris cet exemple (brique/mur de briques) pour montrer la composition. Dans mon programme, ces 2 classes ont des comportement tres tres similaires, d'ou ma relation d'heritage.

explique ton problème, décris tes classes sans avoir recours à un exemple du 'vrai monde' (mur / brique). un tel exemple est souvent très mal adapté.  
 
de ton petit bémol, on peut déduire que si les deux classes ont des comportement très similaires, elles sont les spécialisations d'un comportement abstrait. applique ce que te disait BifaceMcLeOD et dérive ces deux classes d'une nouvelle classe abstraite.
 
ou dis-en plus. peut-être que tu essayes de corriger un symptôme plutôt qu'un plus gros problème de design.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed