This can happen because Parent may not have a virtual destructor. Since you are creating Parent* (the base class) for the dynamically distributed child derived class, removing Parent* , which does not have a virtual destructor, will lead to undefined behavior, but usually will cause the derived class to not be destroyed.
From Scott Myers - Effective C ++ 3rd Edition :
... if we remove the base class pointer with a non-virtual destructor, the results will be undefined. What usually happens at runtime is that the derived part of the object is never destroyed. This is a great way to leak resources, damaged data structures, and spend a lot of time with the debugger. Thus, any class with virtual functions should have an almost 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;
You can fix this by creating a Parent virtual destructor:
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? who probably explain it better than I did
Change Thanks to @aschepler (in the comments for comments), the commentators below and the answer to the related question, I updated the answer to better understand that this is undefined behavior. In my haste, I didn’t mention this and only mentioned typical behavior
source share