Destructeur virtuel pur en C ++

163

Est-ce mal d'écrire:

class A {
public:
    virtual ~A() = 0;
};

pour une classe de base abstraite?

Au moins cela compile dans MSVC ... Est-ce que ça plantera au moment de l'exécution?

Ivan Krechetov
la source
9
Il peut compiler, mais est-il lié?
Mooing Duck

Réponses:

218

Oui. Vous devez également implémenter le destructeur:

class A {
public:
    virtual ~A() = 0;
};

inline A::~A() { }

devrait suffire.

Et comme cela a obtenu un vote défavorable, je devrais clarifier: si vous dérivez quelque chose de A et essayez ensuite de le supprimer ou de le détruire, Ale destructeur de s sera finalement appelé. Puisqu'il est pur et n'a pas d'implémentation, un comportement indéfini s'ensuivra. Sur une plate-forme populaire, cela invoquera le gestionnaire purecall et plantera.

Edit: correction de la déclaration pour qu'elle soit plus conforme, compilée avec http://www.comeaucomputing.com/tryitout/

MSN
la source
16
Euh, oui ça l'est. Pure signifie uniquement qu'une classe dérivée doit également fournir une implémentation.
MSN
72
La mise en œuvre de fonctions virtuelles pures est en fait légale. Très utile pour fournir une implémentation par défaut mais obliger les sous-classes à l'appeler explicitement.
jmucchiello
6
MSN et notez que si vous avez cette définition dans l'en-tête, vous devez mettre "inline" avant cela pour éviter de violer l'ODR (règle d'une définition)
Johannes Schaub - litb
2
Pourquoi A :: ~ A () doit-il être défini explicitement, puisque je pensais qu'il y avait un destructeur par défaut pour chaque objet? Comme dans tout type d'héritage, la chaîne de destructeurs est toujours appelée et le destructeur de classe de base n'a pas besoin d'être toujours défini.
jeffD
11
Une meilleure façon de le dire est qu'une fois que vous déclarez un destructeur, il n'est pas automatiquement implémenté pour vous.
MSN
49

Destructeurs privés: ils vous donneront une erreur lorsque vous créez un objet d'une classe dérivée - pas autrement. Un diagnostic peut cependant apparaître.

12.4 Destructeurs

6 Un destructeur peut être déclaré virtuel (10.3) ou pur virtuel (10.4); si des objets de cette classe ou de toute classe dérivée sont créés dans le programme, le destructeur doit être défini.

Une classe avec un destructeur virtuel pur est une classe abstraite. Note bien:

10.4 Classes abstraites

2 Une fonction virtuelle pure n'a besoin d'être définie que si elle est appelée avec, ou comme si avec (12.4), la syntaxe d'ID qualifié (5.1).

[ Remarque : une déclaration de fonction ne peut pas fournir à la fois un spécificateur pur et une définition - note de fin]

Tiré directement du brouillon:

struct C {
   virtual void f() = 0 { }; // ill-formed
};
dirkgently
la source
14
+1. Je pense qu'Herb Sutter a également de bonnes informations à ce sujet: gotw.ca/gotw/031.htm . Il est intéressant de noter que toute fonction virtuelle pure peut avoir une implémentation fournie, pas seulement des destructeurs.
Fred Larson
6
Oui, c'est quelque chose que vous faites dans une interview pour effrayer vos intervieweurs;)
dirkgently
1
Ce n'est en fait pas si rare, d'après mon expérience.
@Neil Butterworth: Lequel?
dirkgently
@Dirk - le scénario "toute fonction". Il n'est pas rare de le trouver utilisé pour implémenter un comportement courant.