Les fonctions virtuelles

Les fonctions virtuelles

Typage statique des objets (ou ligature dynamique des fonctions)

Les règles de compatibilité entre une classe de base et une classe dérivée permettent d’affecter à un pointeur sur une classe de base la valeur d’un pointeur sur une classe dérivée. Toutefois, par défaut, le type des objets pointés est défini lors de la compilation. Par exemple, avec : class A class B : public A { ….. { ….. public : public : void fct (…) ; void fct (…) ; ….. ….. } ; } ; A * pta ; B * ptb ; une affectation telle que pta = ptb est autorisée. Néanmoins, quel que soit le contenu de pta (autrement dit, quel que soit l’objet pointé par pta), pta->fct(…) appelle toujours la fonction fct de la classe A.

Les fonctions virtuelles

L’emploi des fonctions virtuelles permet d’éviter les problèmes inhérents au typage statique. Lorsqu’une fonction est déclarée virtuelle (mot-clé virtual) dans une classe, les appels à une telle fonction ou à n’importe laquelle de ses redéfinitions dans des classes dérivées sont « résolus » au moment de l’exécution, selon le type de l’objet concerné. On parle de typage dynamique des objets (ou de ligature dynamique des fonctions). Par exemple, avec : class A class B : public A { ….. { ….. public : public : virtual void fct (…) ; void fct (…) ; ….. ….. }; } ; A * pta ; l’instruction pta->fct (…) appellera la fonction fct de la classe correspondant réellement au type de l’objet pointé par pta. N.B. Il peut y avoir ligature dynamique même en dehors de l’utilisation de pointeurs (voyez, par exemple, l’exercice 65). Règles ■ Le mot-clé virtual ne s’emploie qu’une fois pour une fonction donnée ; plus précisément, il ne doit pas accompagner les redéfinitions de cette fonction dans les classes dérivées. ■ Une méthode déclarée virtuelle dans une classe de base peut ne pas être redéfinie dans ses classes dérivées. ■ Une fonction virtuelle peut être surdéfinie (chaque fonction surdéfinie pouvant être ou ne pas être virtuelle). ■ Un constructeur ne peut pas être virtuel, un destructeur peut l’être. ■ Par sa nature même, le mécanisme de ligature dynamique est limité à une hiérarchie de classes ; souvent, pour qu’il puisse s’appliquer à toute une bibliothèque de classes, on sera amené à faire hériter toutes les classes de la bibliothèque d’une même classe de base.

Les fonctions virtuelles pures

Une « fonction virtuelle pure » se déclare avec une initialisation à zéro, comme dans : virtual void affiche () = 0 ; exos_c++.book Page 226 Jeudi, 5. juillet 2007 11:10 11 © Éditions Eyrolles 227 chapitre n° 15 Les fonctions virtuelles Lorsqu’une classe comporte au moins une fonction virtuelle pure, elle est considérée comme « abstraite », c’est-à-dire qu’il n’est plus possible de créer des objets de son type. Une fonction déclarée virtuelle pure dans une classe de base peut ne pas être déclarée dans une classe dérivée et, dans ce cas, elle est à nouveau implicitement fonction virtuelle pure de cette classe dérivée (avant la version 3.0, une fonction virtuelle pure devait obligatoirement être redéfinie dans une classe dérivée ou déclarée à nouveau virtuelle pure). Exercice 115 Énoncé Quels résultats produira ce programme : #include using namespace std ; class point { protected : // pour que x et y soient accessibles à pointcol int x, y ; public : point (int abs=0, int ord=0) { x=abs ; y=ord ; } virtual void affiche () { cout << « Je suis un point \n » ; cout <<  » mes coordonnées sont :  » << x <<  »  » << y << « \n » ; } } ; class pointcol : public point { short couleur ; public : pointcol (int abs=0, int ord=0, short cl=1) : point (abs, ord) { couleur = cl ; } void affiche () { cout << « Je suis un point coloré \n » ; cout <<  » mes coordonnées sont :  » << x <<  »  » << y ; cout <<  » et ma couleur est :  » << couleur << « \n » ; } } ; main() { point p(3,5) ; point * adp = &p ; pointcol pc (8,6,2) ; pointcol * adpc = &pc ;

Formation et coursTélécharger le document complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *