que - polimorfismo puro c++
¿Una clase virtual pura de C++ necesita una definición? (4)
¿Una clase virtual pura de C ++ necesita una definición?
El primer error es inventar términos en nombre propio. No existe tal cosa como "una clase virtual pura". Solo hay "función virtual" y "función virtual pura". Comprender que no hay tal cosa como "clase virtual pura" es una clave para entender por qué esta pregunta no es válida.
Solía pensar que la clase virtual pura define una interfaz (declaración de función)
Creo que C ++ no es tu primer idioma, sino un segundo idioma después de Java / C #, y piensas en las ideas de Java / C # que no tienen nada que ver con C ++.
C ++ tiene interfaces, es solo la declaración de la clase:
struct A{
void doNothing();
};
//A.cpp:
void A::doNothing(){
}
Esta es la interfaz de la estructura A. ¿Tiene algo que ver con la herencia, las funciones virtuales o el polimorfismo? No. Es solo la declaración de la clase, qué método y propiedades existen dentro de ella.
Cada clase necesita un destructor válido para permitir que el programa limpie los recursos del objeto: memoria, etc. No tiene nada que ver con el polimorfismo. En su ejemplo, A
necesita ser destruido de alguna manera. No importa que B
herede de eso. Debe decirle al programa cómo lidiar con él cuando se sale del alcance.
Como se menciona en los comentarios, si solo desea un destructor virtual (para que no se manifieste UB en el caso de A* a = new B()
), simplemente declare el destructor como predeterminado:
virtual ~A() = default;
Esta pregunta ya tiene una respuesta aquí:
- Destructor virtual puro en C ++ 2 respuestas
Considerar:
// in header.h
class A {
public:
virtual ~A() = 0;
};
class B : public A {
public:
~B() override {}
}
El vinculador informa que no puede resolver:
símbolo externo "public: virtual __thiscall A :: ~ A (void)" referenciado en la función "public: virtual __thiscall B :: ~ B (void)"
Encuentro que tengo que escribir la definición de A::~A()
.
Solía pensar que una clase virtual pura define la interfaz (declaración de función), y no tienen que contener una definición de función. ¿Debo escribir definiciones para todas las funciones virtuales en una clase base virtual pura? ¿O debería simplemente escribir la función de destructor?
Bueno, para hacer un resumen de clase necesitas hacer al menos una función virtual pura. Si no tiene otro, entonces destructor podría ser un buen candidato. Pero en otro lado, destructir es un caso especial: debes definirlo incluso si es puro.
Nota: también puede definir la función virtual pura regular para interceptar la condición de error (algo así como la función pura se llama desde ctor o dtor), pero a diferencia del destructor está bien no proporcionar dicha definición y el compilador generaría el controlador de errores allí, lo que hará informa que llama a la función virtual pura.
Como complemento de mis predecesores, puedes leer sobre esto aquí .
La definición de una función virtual pura puede proporcionarse ( y debe proporcionarse si el virtual puro es el destructor ): las funciones miembro de la clase derivada son libres de llamar a la función virtual pura de la base abstracta utilizando la id. De función calificada. Esta definición debe proporcionarse fuera del cuerpo de la clase (la sintaxis de una declaración de función no permite tanto el especificador puro = 0 como el cuerpo de una función)
Es porque a diferencia de las funciones virtuales regulares, un destructor no se anula . Cuando llama a una función virtual normal en una clase base, termina llamando solo a la función que ha anulado esa función.
En el caso del destructor, sin embargo, los destructores de las clases base también deben ser llamados. Pero dado que no proporciona una implementación de ~A()
, su código no se puede vincular.
Pero puede definir la función aunque sea puramente virtual: como aquí .