2012-05-22 40 views
17

Entiendo por qué ocurre esto, pero estoy atascado tratando de resolverlo ... esto es lo que mi código está haciendo cuando se genera el error (por lo tanto, provoca un bloqueo)) cuando mi programa sale ...Cómo resolver "método virtual puro llamado"

pure virtual method called

SomeClass::~SomeClass() 
{ 
    BaseClassObject->SomePureVirtualMethod(this); 
} 

void DerivedClass::SomePureVirtualMethod(SomeClass* obj) 
{ 
    //Do stuff to remove obj from a collection 
} 

nunca tener una llamada a new SomeClass pero tengo una QList<SomeClass*> la que añado SomeClass* objetos a. El propósito de este destructor en SomeClass es indicar DerivedClass para eliminar una instancia específica de SomeClass de su colección de QList<SomeClass*>.

Así, en un ejemplo concreto ...

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties que posee una referencia a Shape

Por lo tanto, nunca tengo una llame al new ShapeProperties pero tengo un QList<ShapeProperties*> dentro de Triangle. El destructor en ShapeProperties debe indicar Triangle para eliminar una propiedad específica de ShapeProperties de su colección de QList<ShapeProperties*>.

Respuesta

28

En el momento en que 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 se puede considerar eficazmente igual que el tipo estático. Es decir, cuando llama a métodos virtuales desde sus constructores/destructores, no se llaman las versiones anuladas de ellos.

Si necesita invocar SomePureVirtualMethod en el destructor, tendrá que llamarlo dentro del destructor de la clase donde está la definición real del método que desea.

+0

Entonces, ¿cómo sé a qué instancia de 'this' me refiero si lo llamo en el constructor derivado? – user869525

+0

@ user869525: ¿Podría intentar reformular eso? No entendí ... –

+0

Probablemente malinterpreté esto, "Si' SomePureVirtualMethod' necesita ser llamado en el destructor, entonces tendrás que llamarlo dentro del destructor de la clase donde está la definición real del método que deseas. " – user869525

8

Cuando se llama al método virtual en el destructor de la clase base SomeClass llama al método (SomePureVirtualMethod()) de la clase SomeClass base que es un método virtual pura sin definición. Y de ahí el error.

¿Por qué sucede esto?
El tipo de this en constructor o destructor es del tipo cuyo constructor o destructor se está llamando y, por lo tanto, el despacho dinámico no funciona en constructores y destructores como cabría esperar en todas las demás funciones.

¿Por qué se cuelga?
Porque llamar a una función virtual pura desde constructor o destructor es Comportamiento indefinido.

C++ 03 10.4/6 estados

"Las funciones miembro se puede 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 ser creado (o destruido) de tal constructor (o destructor) no está definido ".

¿Cómo evitarlo?
Solo asegúrese de no llamar a una función virtual pura desde el constructor o el destructor.
No llame a los métodos virtual en constructor o destructor a menos que comprenda la dinámica involucrada.

Cuestiones relacionadas