Destructor virtual puro en C ++

163

¿Está mal escribir:

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

para una clase base abstracta?

Al menos eso se compila en MSVC ... ¿Se bloqueará en tiempo de ejecución?

Ivan Krechetov
fuente
9
Puede compilarse, pero ¿se vincula?
Mooing Duck

Respuestas:

218

Si. También necesita implementar el destructor:

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

inline A::~A() { }

Debería ser suficiente.

Y dado que esto obtuvo un voto negativo, debo aclarar: si obtiene algo de A y luego trata de eliminarlo o destruirlo, Afinalmente se llamará al destructor. Como es puro y no tiene una implementación, se producirá un comportamiento indefinido. En una plataforma popular, invocará el controlador de llamada pura y se bloqueará.

Editar: arreglando la declaración para que sea más conforme, compilada con http://www.comeaucomputing.com/tryitout/

MSN
fuente
16
Um, si lo es. Puro solo significa que una clase derivada también necesita proporcionar una implementación.
MSN
72
Implementar funciones virtuales puras es de hecho legal. Muy útil para proporcionar una implementación predeterminada, pero obliga a las subclases a llamarla explícitamente.
jmucchiello
66
MSN y nota si tiene esa definición en la cabecera, es necesario poner "en línea" antes de que para evitar violar la ODR (una regla de definición)
Johannes Schaub - litb
2
¿Por qué A :: ~ A () tiene que definirse explícitamente, ya que pensé que hay un destructor predeterminado para cada objeto? Como en cualquier tipo de herencia, la cadena de destructores siempre se llama y el destructor de la clase base no tiene que estar siempre definido.
jeffD
11
Una mejor manera de decirlo es que una vez que declaras un destructor, no se implementa automáticamente para ti.
MSN
49

Destructores privados: le darán un error cuando cree un objeto de una clase derivada, no de otra manera. Sin embargo, puede aparecer un diagnóstico.

12.4 Destructores

6 Un destructor puede declararse virtual (10.3) o virtual puro (10.4); Si se crea algún objeto de esa clase o cualquier clase derivada en el programa, se definirá el destructor.

Una clase con un destructor virtual puro es una clase abstracta. Buena nota:

10.4 Clases abstractas

2 Una función virtual pura solo debe definirse si se llama con, o como con (12.4), la sintaxis de id calificada (5.1).

[ Nota : una declaración de función no puede proporcionar tanto un especificador puro como una definición: nota final]

Tomado directamente del borrador:

struct C {
   virtual void f() = 0 { }; // ill-formed
};
Dirkgently
fuente
14
+1. Creo que Herb Sutter también tiene buena información sobre esto: gotw.ca/gotw/031.htm . Es interesante notar que cualquier función virtual pura puede tener una implementación provista, no solo destructores.
Fred Larson
66
Sí, es algo que haces en una entrevista para asustar a tus entrevistadores;)
Dirkgently
1
En realidad, no es tan raro, en mi experiencia.
@Neil Butterworth: ¿Cuál?
Dirkgently
@Dirk: el escenario "cualquier función". No es raro encontrar que se utiliza para implementar un comportamiento común.