This can happen because Parent
may not have a virtual destructor. Since you are creating a Parent*
(the base class) to a dynamically allocated derived class Child
, deleting the Parent*
which has no virtual destructor will cause undefined behaviour, but typically will result in the derived class not being destroyed.
From Scott Myers - Effective C++ Third Edition:
... if we delete Base class pointer with a non-virtual destructor, results are undefined. What typically happens at runtime is that the derived part of the object is never destroyed. This is an excellent way to leak resources, corrupt data structures, and spend a lot of time with a debugger. So any class with virtual functions should almost certainly have a virtual destructor.
class Parent{
};
class Child:public Parent{
public:
Child() : str("Child") {}
~Child() { std::cout << str << std::endl;};
std::string str;
};
int main(){
Parent *ptr=new Child();
delete ptr; // undefined behaviour: deleting a Base* to a Derived object where the Base has no virtual destructor
}
You can fix this by making Parent
's destructor virtual
:
class Parent{
public:
virtual ~Parent() {} // Will call derived classes destructors now as well
};
class Child:public Parent{
public:
Child() : str("Child") {}
~Child() { std::cout << str << std::endl;};
std::string str;
};
int main(){
Parent *ptr=new Child();
delete ptr;
// Child::~Child() has now been called.
}
See When to use virtual destructors? which probably explains it better than I did
Edit: Thank you to the @aschepler (in the question's comments), commenters below, and the answer to the linked question, I have updated the answer to better reflect that this is undefined behaviour. In my haste I didn't mention it, and only mentioned the typical behaviour