Une classe est abstraite lorsque lune au moins de ses méthodes virtuelles est pure. Pour déclarer une méthode virtuelle pure, il suffit de ne pas donner dimplantation et décrire = 0
; derrière sa déclaration. Seules les fonctions virtuelles peuvent être déclarées pures, sous peine derreur (Error : Non-virtual function 'xxx' declared pure).
Lorsquune classe est abstraite, elle ne peut être utilisée directement ; en particulier, on ne peut pas déclarer dobjets de cette classe, ni darguments ou de résultats de fonction. Si vous tentez de le faire, vous obtiendrez Error : Cannot create a variable for abstract class 'xxx', on ne peut pas créer une variable de la classe abstraite 'xxx'.
On peut par contre utiliser des références, des pointeurs et dériver de nouvelles classes, et cest en fait lusage de ces classes abstraites. Voici comment déclarer une classe abstraite liste
, puis les deux classes de listes concrètes identiques à celles du chapitre 6 :
class liste { // classe abstraite protected : int nombre; public : virtual ~liste() { nombre = 0; }; virtual void avance(int combien = 1) = 0; // pure void recule(int combien = 1) { avance(-combien); } virtual element& valeur(void) = 0; // pure unsigned nombre_elt(void) { return nombre; } void affiche(unsigned combien = 65535); virtual int insere(const element&) = 0; // pure virtual void supprime(int n = 1) = 0; // pure };class listech : public liste { // liste chaînée noeud* courant; public : listech() { nombre = 0; courant = 0; } listech(int n, const element*); // c. avec table ~listech(); void avance(int combien = 1); element& valeur(void) { if (courant) return courant->contenu(); } int insere(const element&); void supprime(int n = 1); };class listetab : public liste { element *tab, *courant; public : listetab() { courant = tab = 0; } listetab(int n, const element*); // c. avec table ~listetab(); void avance(int combien = 1); element& valeur(void) { if (courant) return *courant; } int insere(const element&); void supprime(int n = 1); };
La classe liste
est abstraite, puisque quatre de ses méthodes ont été déclarées pures. On notera que certaines ne le sont pas : il sagit essentiellement (et pas par hasard) de celles qui nétaient pas virtuelles dans notre exemple précédent.
Le petit programme de démonstration reste identique, sauf que le premier élément de listes
doit être initialisé en écrivant new listech...
, au lieu de new liste
.
Les classes abstraites nont généralement pas de constructeur, sauf si linitialisation des membres est un peu compliquée (ici il suffit de mettre la valeur adéquate dans le champ nombre
, et les constructeurs de listch
et listtab
le font). Par contre, il est généralement souhaitable dy placer un destructeur virtuel, même sil ne fait rien comme dans notre exemple : on est ainsi certain de la bonne destruction des objets des classes dérivées.
Exercice 8.4 | Comment créer un opérateur daffectation pour les listes ? Et les constructeurs de copie ? |
Voir solution |
Ce type de classe peut paraître curieux au premier abord. En fait, il est assez pratique, notamment quand, comme dans notre exemple, on souhaite implanter de plusieurs façons différentes une forme dobjet ; lutilisateur na plus alors quà choisir celle quil préfère. Le seul inconvénient, assez léger, vient de ce quil faut utiliser des pointeurs dans ce cas ; cela évite cependant de se tromper en utilisant un tableau de liste
alors quil faut un tableau de pointeurs.
Précédent | Sommaire | Suivant |