Destruidor virtual puro em C ++

163

É errado escrever:

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

para uma classe base abstrata?

Pelo menos isso compila no MSVC ... Ele trava no tempo de execução?

Ivan Krechetov
fonte
9
Pode ser compilado, mas vincula?
Mooing Duck

Respostas:

218

Sim. Você também precisa implementar o destruidor:

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

inline A::~A() { }

deve ser suficiente.

E uma vez que houve uma votação negativa, devo esclarecer: se você extrair algo de A e tentar excluí-lo ou destruí-lo, Ao destruidor de eventualmente será chamado. Como é puro e não possui uma implementação, um comportamento indefinido se seguirá. Em uma plataforma popular, isso invocará o manipulador de chamadas e falhas.

Editar: corrigindo a declaração para ser mais compatível, compilada com http://www.comeaucomputing.com/tryitout/

MSN
fonte
16
Hum, é sim. Puro apenas significa que uma classe derivada também precisa fornecer uma implementação.
MSN
72
A implementação de funções virtuais puras é de fato legal. Muito útil para fornecer uma implementação padrão, mas forçar as subclasses a chamá-lo explicitamente.
jmucchiello
6
MSN e nota se você tiver essa definição no cabeçalho, você precisa colocar "inline" antes para evitar violar o ODR (uma regra de definição)
Johannes Schaub - litb
2
Por que A :: ~ A () precisa ser explicitamente definido, pois pensei que existe um destruidor padrão para cada objeto? Como em qualquer tipo de herança, a cadeia de destruidores é sempre chamada e o destruidor da classe base nem sempre precisa ser definido.
11119 jeffD
11
Uma maneira melhor de dizer isso: depois que você declara um destruidor, ele não é implementado automaticamente para você.
MSN
49

Destruidores particulares: eles darão um erro quando você criar um objeto de uma classe derivada - não de outra forma. Um diagnóstico pode aparecer.

12.4 Destrutores

6 Um destruidor pode ser declarado virtual (10.3) ou virtual puro (10.4); se quaisquer objetos dessa classe ou de qualquer classe derivada forem criados no programa, o destruidor deve ser definido.

Uma classe com um destruidor virtual puro é uma classe abstrata. Observe bem:

10.4 Classes abstratas

2 Uma função virtual pura precisa ser definida apenas se for chamada com ou como (12.4), a sintaxe de identificação qualificada (5.1).

[ Nota : uma declaração de função não pode fornecer um especificador puro e uma definição - end note]

Retirado direto do rascunho:

struct C {
   virtual void f() = 0 { }; // ill-formed
};
dirkgently
fonte
14
+1. Eu acho que Herb Sutter também tem algumas boas informações sobre isso: gotw.ca/gotw/031.htm . É interessante notar que qualquer função virtual pura pode ter uma implementação fornecida, não apenas destruidores.
11553 Fred Larson
6
Sim, é algo que você faz em uma entrevista para assustar seus entrevistadores;)
dirkgently
1
Na verdade, não é tão incomum, na minha experiência.
@ Neil Butterworth: Qual?
dirkgently
@Dirk - o cenário "qualquer função". Não é incomum encontrá-lo usado para implementar algum comportamento comum.