On peut bien sûr créer un opérateur daffectation pour chaque classe concrète, mais cela ne permet pas de faire des affectations de lune de ces classes à lautre. Voici une solution à ce problème, basée sur la remarque simple que les méthodes de liste
permettent de connaître entièrement le contenu dune liste, et donc den construire une copie :
class liste { // classe abstraite // ... virtual liste& operator=(liste&) = 0; };class listech : public liste { // ... listech(liste& ls) { nombre = 0; *this = ls; } listech(listech& lc) { nombre = 0; *this = lc; } liste& operator=(liste&); };class listetab : public liste { / /... listetab(liste& ls) { nombre = 0; *this = ls; } listetab(listetab& lt) { nombre = 0; *this = lt;} liste& operator=(liste&); };liste& listech::operator=(liste& ls)// copie une liste dans this{ supprime(nombre); int reste = ls.nombre_elt(); if (!reste) return *this; noeud *np = 0; while ( (np = new noeud(ls.valeur(), courant = np)) && (reste--) ) { ls.avance(); nombre++; } ls.avance(reste); // rétablir début if (np) courant = np->suivant(); return *this;}liste& listetab::operator=(liste& ls)// copie la liste dans this{ supprime(nombre); if ( !ls.nombre_elt() || !(tab = new element[ls.nombre_elt()]) ) return *this; courant = tab; nombre = ls.nombre_elt(); for (int i = nombre; i; i--) { *courant++ = ls.valeur(); ls.avance(); } courant = tab; return *this;}
On notera que dans le cas de la classe listech
par exemple, il faut définir un constructeur de copie pour un argument de liste&
et un pour un argument listech&
, bien quil y ait une conversion automatique de la seconde classe vers la première ; en effet, le premier constructeur avec son argument liste&
nest pas considéré comme un constructeur de copie par C++, puisquil ninclut aucun argument de type listech&
; de ce fait, le compilateur fournit un constructeur implicite qui fait une copie membre à membre, ce qui nest pas souhaitable ici. Le même raisonnement vaut pour listetab
évidemment.
Remarquer également que la copie nest pas parfaitement identique dans ses effets dans les deux cas, sil ny a pas assez de mémoire : listech
recopie tout ce qui est possible, tandis que listetab
ne recopie rien.