Entiendo por qué sucede esto, pero estoy atascado tratando de resolverlo … esto es lo que hace mi código cuando se genera el error (lo que provoca una falla) cuando mi progtwig sale …
pure virtual method called
SomeClass::~SomeClass() { BaseClassObject->SomePureVirtualMethod(this); }
void DerivedClass::SomePureVirtualMethod(SomeClass* obj) { //Do stuff to remove obj from a collection }
Nunca recibí una llamada a la new SomeClass
pero tengo una QList
que SomeClass*
objetos SomeClass*
. El propósito de este destructor en SomeClass
es decirle a DerivedClass
que elimine una instancia específica de SomeClass
de su colección de QList
.
Entonces, en un ejemplo concreto …
BaseClass
= Shape
DerivedClass
= Triangle
SomeClass
= ShapeProperties
que posee una referencia a Shape
Por lo tanto, nunca tengo una llamada a las new ShapeProperties
pero tengo una QList
dentro de Triangle
. El destructor en ShapeProperties
es decirle a Triangle
que elimine una propiedad específica de ShapeProperties
de su colección de QList
.
Cuando se llama a su destructor, ya se ha llamado al destructor de clases heredadas. Dentro de los constructores y destructores, el tipo dynamic del objeto puede considerarse efectivamente como el tipo estático. Es decir, cuando llama a métodos virtuales desde sus constructores / destructores, no se llama a las versiones anuladas de ellos.
Si SomePureVirtualMethod
necesario SomePureVirtualMethod
a SomePureVirtualMethod
en el destructor, entonces deberá llamarlo dentro del destructor de la clase donde está la definición real del método que desea.
Cuando llama al método virtual
en el destructor de la clase Base SomeClass
, llama al método ( SomePureVirtualMethod()
) de la clase Base SomeClass
que es un método virtual puro sin definición. Y de ahí el error.
¿Por qué pasó esto?
El tipo de this
en el constructor o destructor es del tipo al que se llama el constructor o destructor y, por lo tanto, el envío dynamic no funciona en los constructores y destructores, como es de esperar que funcione en todas las demás funciones.
¿Por qué se estrella?
Porque llamar a una función virtual pura desde un constructor o destructor es un comportamiento indefinido .
C ++ 03 10.4 / 6 estados
“Las funciones miembro se pueden llamar desde un constructor (o destructor) de una clase abstracta; el efecto de hacer una llamada virtual (10.3) a una función virtual pura directa o indirectamente para el objeto que se crea (o destruye) desde dicho constructor ( o destructor) es indefinido “.
¿Cómo evitarlo?
Solo asegúrese de no llamar a una función virtual pura desde el constructor o el destructor.
No llame a virtual
métodos virtual
en el constructor o destructor a menos que entienda la dinámica involucrada.