Liste chainée d'objets de classes différentes

gillig Messages postés 32 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 4 décembre 2003 - 16 juil. 2003 à 14:58
gillig Messages postés 32 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 4 décembre 2003 - 30 oct. 2003 à 03:22
Voici un problème auquel je ne trouve pas de réponse, enfin, rien d'efficace.
J'ai une classe CDessin contenant une liste chaînée (CList) de pointeurs d'objets CForme. Je voudrais ajouter une méthode Ajout(CForme *pForme), à laquelle je passerais des pointeurs vers des objets dérivés de CForme, disons CCarre, CSphere, CLigne, etc. Jusque là, rien de compliqué (liste.AddTail(pForme)).
Mais ça se complique. Je souhaiterais NE PAS ajouter une sphère qui aurait le même centre et le même rayon qu'une autre déjà présente. Donc, dans le parcours de la liste à la recherche d'un éventuel doublon, il faut 1) ne pas se préoccuper des objets de classe différente, et 2) pour des objets de même classe, les comparer en fonctions de critères spécifiques à la classe.
Comment faire ?
Voici les solutions auxquelles j'ai pensé :
- 1 liste chainée par classe + 1 méthode d'ajout par classe. Bof...
- 1 liste chainée par classe + 1 switch sur le type de pForme*. Bof pareil...
- 1 seule liste, et surcharger les opérateurs == pour toutes les sous-classes de CForme et en faisant toutes les combinaisons. Lourd, et d'ailleurs je ne suis pas sûr que ça puisse marcher...
Merci d'avance pour votre aide ! J'ajoute que je suis un peu pressé...

2 réponses

cs_Kaid Messages postés 949 Date d'inscription mardi 2 octobre 2001 Statut Membre Dernière intervention 8 juillet 2006 1
16 juil. 2003 à 17:35
Désolé, mais tu es obligé de définir l'opérateur de comparaison == dans la classe CForme et toutes ses sous-classes sinon impossible de savoir si deux formes ont des caractéristiques identiques.

Sinon pour l'ajout, la meilleure manière de procéder (une liste avec tous les types d'objets, n listes) dépend de la quantité d'objets CForme que tu vas manipuler.

Kaid - kaid.fr.st
0
gillig Messages postés 32 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 4 décembre 2003
30 oct. 2003 à 03:22
Merci pour ta réponse rapide. Je me suis débrouillé comme je pouvais avant de ... laisser passer un peu de temps et continuer de chercher.

J'ai envisagé d'abord la possibilité de définir un énuméré ({CERCLE, CARRE, ...}) et de m'en servir comme base pour reconnaitre 2 objets de même classe. Mais bon...

Je crois avoir trouvé une meilleur solution en utilisant l'opérateur typeid, qui récupère dynamiquement le type, et qui fourni non seulement un opérateur == , mais aussi une méthode "before" censée indiquer si les 2 classes font partie de la même hiérarchie :

bool CForme::EstMemeClasseOuSousClasse(const CForm *f)
{
const type_info &t1 = typeid(*this);
const type_info &t2 = typeid(*f);
return (t1 == t2 || t2.before(t1));
}

bool CSphere::operator==(const CForme &f)
{
if (EstMemeClasseOuSousClasse(&f))
{
CSphere *f2 = (CSphere *) &f;
return (_rayon==f2->_rayon && ...);
}
return false;
}

CForme * CMoteur::Ajout(CForme *pForme)
{
if (!pForme) return;
POSITION pos = _lstFormes.GetHeadPosition();
bool trouve = false;
int i = _lstFormes.GetCount();
while (i-- > 0 && !trouve)
{
CForme *f = _lstFormes.GetNext(pos);trouve (*pForme *f);
}
...
}

NB : cocher la case Enable Run-Time Type Information (RTTI) dans les options de compilation
0
Rejoignez-nous