Vidéo: Virtual Functions & Abstract Classes in C++ | C++ Programming Tutorials 2025
C ++ prend en charge late binding , qui résout un appel de méthode basé sur l'exécution type (ou type dynamique) de l'objet cible plutôt que son type déclaré (ou type statique). Cela est illustré dans l'extrait de code C ++ suivant:
#include using namespace std; class Oven {public: cuisinier vide virtuel () {cout << "cuisiner avec un four" << endl;}}; classe MicrowaveOven: four public {public: cuisinier vide virtuel () {cout << "cuisinant avec un four à micro-ondes" << endl;}}; void prepareMeal (four et four) {four. cook ();
Dans la fonction prepareMeal (), l'appel au four. cook () peut passer à Oven:: cook () ou MicrowaveOven:: cook () en fonction du type d'exécution (le type "actuel") de l'objet du four passé.
Le mot clé virtuel est critique ici. Sans elle, la méthode cook () serait liée tôt, en fonction du type de compilation, et invoquerait Oven:: cook () à chaque fois. Une fois déclarée virtuelle dans la classe Oven, la méthode est supposée être virtuelle dans chaque sous-classe, mais cela ne fait pas de mal de répéter la déclaration pour que les lecteurs comprennent.
Le programme simple suivant démontre ce principe dans la pratique:
int main () {Four du four; prepareMeal (four); MicrowaveOven mo; prepareMeal (mo); return 0;}
Dans ce programme, l'appel à cook () génère deux sorties différentes selon le type de four:
Cuisiner avec un four Cuisiner avec un four micro-ondes
Ce n'est pas toujours le cas, qu'une méthode de la classe de base peut être définie. Considérez le cas du four plus attentivement. Il existe différents types de fours - fours conventionnels, fours à convection et fours à micro-ondes - mais on pourrait soutenir qu'il n'y a pas de four qui n'appartienne pas à l'une de ces sous-classes. Vous pourriez être en mesure de dire comment les différents types de fours effectuent l'opération de cuisson - c'est-à-dire, ce que peut faire un conventionnelOven:: cook () et un micro-microwaveOven:: cook (). Il n'est probablement pas possible de définir les actions que Oven:: cook () doit effectuer.
Vous ne pouvez pas simplement quitter Oven:: cook () non déclaré dans un langage fortement typé comme C ++. Cependant, vous pouvez déclarer une méthode mais laissez unimplemented si aucune implémentation n'existe. On utilise la curieuse syntaxe suivante pour le faire:
class Oven {public: virtual void cook () = 0;};
Ce code déclare une méthode Oven:: cook () qui est lié en retard mais n'implémente pas la méthode. En fait, il va plus loin en disant que la méthode ne sera pas mise en œuvre. En C ++, une telle méthode est dite virtuelle pure . Les programmeurs C ++ utilisent également le terme préféré dans de nombreux autres langages informatiques fortement typés: abstract .La classe Oven est dite abstraite.
Un résumé représente une propriété que vous connaissez, mais que vous ne savez pas comment implémenter sans ambiguïté dans la classe en cours.
Une classe est abstraite si elle contient une ou plusieurs méthodes virtuelles pures. La signification de ceci est que vous ne pouvez pas instancier une classe abstraite. Ainsi, ce qui suit n'est plus autorisé:
int main () {Four du four; prepareMeal (four); return 0;}
La raison en est très simple: si vous avez créé un objet de classe Oven et que vous avez essayé d'invoquer oven. cook (), que devrait faire le compilateur?
À un niveau plus philosophique, il est bon de dire qu'il existe un terme commun appelé Four qui décrit les fours conventionnels, les fours à micro-ondes et les fours à convection. Ce terme est un concept habituel car il lie les similitudes dans toutes ces sous-classes. Mais il n'y a pas d'exemple de four qui ne soit pas l'une des sous-classes de Four.
Une sous-classe d'une classe abstraite est elle-même abstraite jusqu'à ce que toutes les méthodes virtuelles pures aient été remplacées par des versions non abstraites (c'est-à-dire concrètes ). Ainsi, la classe MicrowaveOven de l'extrait de code précédent n'est pas abstraite - même si Oven était abstraite - car elle remplace cook () par sa propre version concrète.
Notez qu'il n'y a rien de mal avec la fonction prepareMeal () définie comme suit:
void prepareMeal (Four et four) {four. cook ();}
Même si l'argument est déclaré être un Four, il ne peut être invoqué qu'avec une sous-classe de Four, telle que MicrowaveOven ou ConventionalOven, pour laquelle cook () est défini.
