Classes abstraites (C++)

Les classes abstraites agissent comme des expressions de concepts généraux dont des classes plus spécifiques peuvent être dérivées. Vous ne pouvez pas créer d’objet d’un type de classe abstraite. Toutefois, vous pouvez utiliser des pointeurs et des références aux types de classes abstraits.

Vous créez une classe abstraite en déclarant au moins une fonction membre virtuelle pure. Il s’agit d’une fonction virtuelle déclarée à l’aide de la syntaxe du spécificateur pur (= 0). Les classes dérivées de la classe abstraite doivent implémenter la fonction virtuelle pure, sinon elles aussi sont des classes abstraites.

Prenons l’exemple présenté dans les fonctions virtuelles. L'objectif de la classe Account est de fournir une fonctionnalité générale, mais les objets de type Account sont trop généraux pour être utiles. Cela signifie qu’il s’agit Account d’un bon candidat pour une classe abstraite :

// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
   Account( double d );   // Constructor.
   virtual double GetBalance();   // Obtain balance.
   virtual void PrintBalance() = 0;   // Pure virtual function.
private:
    double _balance;
};

La seule différence entre cette déclaration et la précédente vient du fait que PrintBalance est déclaré avec le spécificateur pure (= 0).

Restrictions sur les classes abstraites

Les classes abstraites ne peuvent pas être utilisées pour :

  • Variables ou données membres

  • Types d’arguments

  • Types de retour de fonction

  • Types de conversions explicites

Si le constructeur d’une classe abstraite appelle une fonction virtuelle pure, directement ou indirectement, le résultat n’est pas défini. Toutefois, les constructeurs et les destructeurs des classes abstraites peuvent appeler d'autres fonctions membres.

Fonctions virtuelles pures définies

Les fonctions virtuelles pures dans les classes abstraites peuvent être définies ou avoir une implémentation. Vous ne pouvez appeler ces fonctions qu’à l’aide de la syntaxe complète :

abstract-class-name ::function-name()

Les fonctions virtuelles pures définies sont utiles lorsque vous concevez des hiérarchies de classes dont les classes de base incluent des destructeurs virtuels purs. C’est parce que les destructeurs de classe de base sont toujours appelés pendant la destruction d’objets. Prenons l’exemple suivant :

// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
    base() {}
    // To define the virtual destructor outside the class:
    virtual ~base() = 0;
    // Microsoft-specific extension to define it inline:
//  virtual ~base() = 0 {};
};

base::~base() {} // required if not using Microsoft extension

class derived : public base
{
public:
    derived() {}
    ~derived() {}
};

int main()
{
    derived aDerived; // destructor called when it goes out of scope
}

L’exemple montre comment une extension de compilateur Microsoft vous permet d’ajouter une définition inline à la machine virtuelle pure ~base(). Vous pouvez également le définir en dehors de la classe à l’aide base::~base() {}de .

Lorsque l’objet sort de l’étendue aDerived , le destructeur de la classe derived est appelé. Le compilateur génère du code pour appeler implicitement le destructeur pour la classe base après le derived destructeur. L’implémentation vide pour la fonction ~base virtuelle pure garantit qu’au moins une implémentation existe pour la fonction. Sans cela, l’éditeur de liens génère une erreur de symbole externe non résolue pour l’appel implicite.

Remarque

Dans l'exemple précédent, la fonction virtuelle pure base::~base est appelée implicitement depuis derived::~derived. Il est également possible d’appeler explicitement des fonctions virtuelles pures à l’aide d’un nom de fonction membre complet. Ces fonctions doivent avoir une implémentation, ou l’appel génère une erreur au moment du lien.

Voir aussi

Héritage