Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve "pure virtual method called"

I understand why this is happening, but I'm stuck trying to resolve it...here is what my code is doing when the error is generated (thus, leading to a crash) when my program exits...

pure virtual method called

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

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

I never have a call to new SomeClass but I have a QList<SomeClass*> which I append SomeClass* objects to. The purpose of this destructor in SomeClass is to tell DerivedClass to remove a specific instance of SomeClass from it's collection of QList<SomeClass*>.

So, in a concrete example...

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties which owns a reference to Shape

So, I never have a call to new ShapeProperties but I have a QList<ShapeProperties*> inside of Triangle. The destructor in ShapeProperties is to tell Triangle to remove a specific property of ShapeProperties from it's collection of QList<ShapeProperties*>.

like image 424
user869525 Avatar asked May 22 '12 17:05

user869525


People also ask

What happens if pure virtual function is called?

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

Is virtual function call is resolved at runtime?

Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for function call. Functions are declared with a virtual keyword in base class. The resolving of function call is done at runtime.

Can a pure virtual function be called using an object?

As well as the standard case of calling a virtual function from the constructor or destructor of an object with pure virtual functions you can also get a pure virtual function call (on MSVC at least) if you call a virtual function after the object has been destroyed.

What happens if you call a pure virtual function C++?

Calling a pure virtual function from a constructor is undefined behaviour even if it has an implementation.


2 Answers

By the time your destructor is called, the destructor of inherited classes has already been called. Within constructors and destructors, the dynamic type of the object can effectively be considered to be the same as the static type. That is, when you call virtual methods from within your constructors/destructors it's not the overriden versions of them that are called.

If SomePureVirtualMethod needs to be called at the destructor, then you will have to call it within the destructor of the class where the actual definition of the method you want is.

like image 197
K-ballo Avatar answered Sep 24 '22 17:09

K-ballo


When you call the virtual method in the destructor of the Base class SomeClass it calls the method(SomePureVirtualMethod()) of the Base class SomeClass which is a pure virtual method with no definition. And hence the error.

Why does this happen?
The type of this in constructor or destructor is of the type whose constructor or destructor is being called and hence dynamic dispatch doesn't work in constructors and destructors as you would expect it to work in all other functions.

Why does it crash?
Because calling a pure virtual function from constructor or destructor is an Undefined Behavior.

C++03 10.4/6 states

"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."

How to avoid it?
Just ensure that you don't call a pure virtual function from constructor or destructor.
Don't call virtual methods in constructor or destructor unless you understand the dynamics involved.

like image 39
Alok Save Avatar answered Sep 21 '22 17:09

Alok Save