C++ virtual destructor

12 Apr 2015

In our latest project we had an issue with a destructor that didn't get called. Our code was something like this:

class SomeInterface {
public:
	virtual void someMethod() = 0;
}

class SomeObject : public SomeInterface {
public:
	~SomeObject();
	virtual void someMethod() {};
}

The object was then deleted while cast to SomeInterface:

SomeObject* someObject = new SomeObject();
SomeInterface* referenceToSomeObject = (SomeInterface*) someObject;
delete referenceToSomeObject;

Guess what: SomeObject's destructor didn't get called! If SomeObject would have had some pointers that would need to be deleted in its destructor, they wouldn't. The issue can be fixed by adding a virtual destructor in the base class SomeInterface:

class SomeInterface {
public:
	virtual ~SomeInterface() {}
	virtual void someMethod() = 0;
}

By making the destructor virtual, you basically tell the compiler it has to call the destructor of the derived class as well. With this change, the destructor of SomeObject will be called when deleting a pointer to SomeInterface. Note that SomeObject's destructor is not virtual. This means that if you would extend SomeObject, the same issue arises. If you are sure your class will not be extended, there is no need to make the destructor virtual. However, in libraries that will be reused it's good to make destructors virtual.

I hope this post was helpful. Memory management is not the easiest thing in C++. Especially when dealing with raw pointers. You could also use shared_ptr and weak_ptr, but we use cocos2d-x, which uses raw pointers for performance reasons.

back to blog
comments powered by Disqus