example - pure virtual function c++
Cómo resolver el "método virtual puro llamado" (2)
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 dinámico 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.
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 programa 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<SomeClass*>
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<SomeClass*>
.
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<ShapeProperties*>
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<ShapeProperties*>
.
Cuando se llama a su destructor, ya se ha llamado al destructor de clases heredadas. Dentro de los constructores y destructores, el tipo dinámico 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.