Héritage et Iterateur de Collection
Bonjour à tous..
Voila j'ai un petit souci. Je programme une collection (class Collection), dont les éléments sont des ColItem (classe ColItem). Pour cela, je fais une liste chainée de ArrayElem (struct ArrayElem). Pour éviter d'utiliser des templates, les classes qui peuvent être mis dans la collection, héritent de ColItem.
Voici les déclaration et les prototypes:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class ColItem
{
public:
ColItem(void);
~ColItem(void);
virtual void Detruir(); // virtual pour le late-binding
virtual void Afficher();
};
struct ArrayElem{
ColItem* Elem;
ArrayElem* next;
}; |
Code:
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 27
|
class Collection:
public ColItem
{
private:
ArrayElem *buffer;
ArrayElem *last;
ArrayElem *iter1;
ArrayElem *iter2;
void SetBuffer(ArrayElem* tBuff);
public:
// constructeurs
Collection();
~Collection();
//fonctions
ColItem* Add(ColItem* bElem);
void Add(char* bDesc,TAG* bTag);
void Clear();
void Afficher();
// iterators:
void bindIterator(ColIterator* bIter);
}; |
et enfin mon itérateur:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
class ColIterator
{
private:
ArrayElem *mCour;
ArrayElem *mHead;
public:
ColIterator();
ColIterator(ArrayElem* head);
~ColIterator();
ColItem* getNext();
bool elemExists();
void gotoHead();
void initHead(ArrayElem* head);
}; |
jusque là, tout est ok. J'arrive à faire marcher mon programme. Mais il y a un "mais".
Pour parcourir la collection, en utilisant les méthodes déclarées virtual (Afficher et Detruir), pas de problème:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
Collection* listElseIfExpr;
Collection* listElseIfCorps;
ColIterator iterElseIfExpr;
ColIterator iterElseIfCorps;
...
listElseIfExpr->bindIterator(&iterElseIfExpr);
listElseIfCorps->bindIterator(&iterElseIfCorps);
while (iterElseIfCorps.elemExists())
{
iterElseIfExpr.getNext()->Afficher();
iterElseIfCorps.getNext()->Afficher();
} |
Mais si je veux accèder à des éléments typés.. Par exemple TypeItem dérive de ColItem et Types est une collection, et si je fais:
Code:
1 2 3 4 5 6 7 8 9
| ColIterator iter1;
TypeItem* Type1;
Types->bindIterator(&iter1);
while(iter1.elemExists()){
Type1 = iter1.getNext();
Type1->Afficher();
} |
la ligne Type1 = iter1.getNext(); donne une erreur de compilation:
Error 1 error C2440: '=' : cannot convert from 'ColItem *' to 'TypeItem *'
or iter1.getNext(); renvoi un ColItem* et Type1 est un TypeItem*. je croyais que c'était censé marcher.
Je veux bien déclarer Type1 en tant que ColItem* mais dans ce cas, comment je peux faire Type1->foncLamba(); sachant que foncLamba() est uniquement dans la classe TypeItem et pas dans ColItem ?
Il existe surement des méthodes pour faire cela proprement. Pour l'instant, je peux faire marcher mon truc en modifiant la ligne Type1 = iter1.getNext(); en Type1 = (TypeItem*)iter1.getNext(); mais bon les casts en C++, question propreté c'est pas ça. Merci d'avance ;)
Re: Héritage et Iterateur de Collection
Citation:
Envoyé par onur
Pour éviter d'utiliser des templates, les classes qui peuvent être mis dans la collection,
Pourquoi ? Même Java (suite à C#) a fini par comprendre qu'un typage plus fort sans downcastings explicites était une bonne solution -- arrivée des generics.
Accessoirement, dans les rares cas où le downcasting est nécessaire, il se préfère avec dynamic_cast<> quand on n'a pas de certitude statique quant au type réel/dynamique, ou avec static_cast<> quand on a cette certitude.
Citation:
héritent de ColItem.
C'est sale les void*, même quand ils sont déguisés en objets.
Citation:
Mais si je veux accèder à des éléments typés.. [...]
Il existe surement des méthodes pour faire cela proprement.
Ouais. Utiliser le polymorphisme paramétrique qui justement est inhérent à la bibliothèque standard du C++ qui fournit déjà ce que tu cherches à réinventer. Ce qui manque a de grandes chances d'être dans boost.
Citation:
mais bon les casts en C++, question propreté c'est pas ça. Merci d'avance ;)
Euh.. C'est un troll ? Tu te rends bien comptes que ce truc, c'est pas vraiment du C++, mais du C avec classes (/java pré 1.5/delphi/.../autres langages dépourvus de polymorphisme paramétrique applicable à la définition de types abstraits) comme on en faisait il y a 15 ans ?
Re: Héritage et Iterateur de Collection
Je suis entièrement d'accord avec Luc.
Citation:
Envoyé par onur
Pour éviter d'utiliser des templates, les classes qui peuvent être mis dans la collection
Pourquoi se casser la tête ? Les templates c'est fait pour ça il me semble non , pour éviter de faire des "casts".
Avec la stl on peut créer des listes en moins de 2...
Citation:
Envoyé par onur
Il existe surement des méthodes pour faire cela proprement. Pour l'instant, je peux faire marcher mon truc en modifiant la ligne Type1 = iter1.getNext(); en Type1 = (TypeItem*)iter1.getNext(); mais bon les casts en C++, question propreté c'est pas ça. Merci d'avance ;)
A part dynamic_cast<> ou static_cast<> ou avoir recours aux templates je ne vois pas autrement... :roll: