web-dev-qa-db-fra.com

Destructeur virtuel pur en C ++

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 qu'il va planter au moment de l'exécution?

154
Ivan Krechetov

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

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

inline A::~A() { }

devrait suffire.

Et comme cela a eu un vote négatif, je devrais préciser: si vous dérivez quelque chose de A puis essayez de le supprimer ou de le détruire, le destructeur de A finira par être appelé. Comme il est pur et n’a pas d’implémentation, il en résulte un comportement indéfini. Sur une plate-forme populaire, cela invoquera le gestionnaire purecall et le crash.

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

202
MSN

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 n'importe quelle 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 ne doit être définie que si elle est appelée avec, ou comme si, avec (12.4), la syntaxe de l’identificateur qualifié (5.1).

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

Tiré directement du projet:

struct C {
   virtual void f() = 0 { }; // ill-formed
};
46
dirkgently