Abstract class
Définit un type abstrait qui ne peut pas être instancié, mais peut être utilisé comme classe de base.
Table des matières |
Syntaxe
Une fonction virtuelle pure est une fonction virtuelle dont le déclarateur a la syntaxe suivante :
declarateur
spécificateur-virtuel
(optionnel)
=
0
|
|||||||||
Ici, la séquence
= 0
est connue sous le nom de
pure-specifier
, et apparaît soit immédiatement après le
declarator
, soit après le
virt-specifier
optionnel (
override
ou
final
).
pure-specifier ne peut pas apparaître dans une définition de fonction membre ou une déclaration friend .
struct Base { virtual int g(); virtual ~Base() {} }; struct A : Base { // OK : déclare trois fonctions membres virtuelles, dont deux pures virtual int f() = 0, g() override = 0, h(); // OK : le destructeur peut également être pur ~A() = 0; // Erreur : spécificateur pur sur une définition de fonction virtual int b() = 0 {} };
Une classe abstraite est une classe qui définit ou hérite d'au moins une fonction pour laquelle le remplacement final est purement virtuel .
Explication
Les classes abstraites sont utilisées pour représenter des concepts généraux (par exemple, Shape, Animal), qui peuvent être utilisés comme classes de base pour des classes concrètes (par exemple, Circle, Dog).
Aucun objet d'une classe abstraite ne peut être créé (sauf pour les sous-objets de base d'une classe dérivée de celle-ci) et aucun membre de données non statique dont le type est une classe abstraite ne peut être déclaré.
Les types abstraits ne peuvent pas être utilisés comme types de paramètres, comme types de retour de fonction, ou comme type d'une conversion explicite (notez que cela est vérifié au point de définition et d'appel de fonction, car au point de déclaration de fonction les types de paramètres et de retour peuvent être incomplets).
Les pointeurs et les références vers une classe abstraite peuvent être déclarés.
struct Abstract { virtual void f() = 0; // virtuelle pure }; // "Abstract" est abstraite struct Concrete : Abstract { void f() override {} // virtuelle non-pure virtual void g(); // virtuelle non-pure }; // "Concrete" est non-abstraite struct Abstract2 : Concrete { void g() override = 0; // redéfinition virtuelle pure }; // "Abstract2" est abstraite int main() { // Abstract a; // Erreur : classe abstraite Concrete b; // OK Abstract& a = b; // OK pour référencer la base abstraite a.f(); // dispatch virtuel vers Concrete::f() // Abstract2 a2; // Erreur : classe abstraite (la redéfinition finale de g() est pure) }
La définition d'une fonction virtuelle pure peut être fournie (et doit l'être si la fonction virtuelle pure est le
destructeur
) : les fonctions membres de la classe dérivée sont libres d'appeler la fonction virtuelle pure de la classe de base abstraite en utilisant l'identifiant qualifié de fonction. Cette définition doit être fournie en dehors du corps de la classe (la syntaxe d'une déclaration de fonction ne permet pas à la fois le spécificateur pur
= 0
et un corps de fonction).
Effectuer un appel virtuel à une fonction virtuelle pure depuis un constructeur ou le destructeur d'une classe abstraite est un comportement indéfini (qu'elle ait une définition ou non).
struct Abstract { virtual void f() = 0; // virtuelle pure virtual void g() {} // virtuelle non-pure ~Abstract() { g(); // OK : appelle Abstract::g() // f(); // comportement indéfini Abstract::f(); // OK : appel non-virtuel } }; // définition de la fonction virtuelle pure void Abstract::f() { std::cout << "A::f()\n"; } struct Concrete : Abstract { void f() override { Abstract::f(); // OK : appelle la fonction virtuelle pure } void g() override {} ~Concrete() { g(); // OK : appelle Concrete::g() f(); // OK : appelle Concrete::f() } };
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| CWG 390 | C++98 | un destructeur virtuel pur non défini pouvait être appelé | une définition est requise dans ce cas |
| CWG 2153 | C++98 | pure-specifier pouvait apparaître dans les déclarations friend | interdit |