Let's say you have a derived class with virtual functions and non-virtual destructor like:
class Base
{
public:
~Base() {}
};
class Derived : public Base
{
public:
Derived() {}
virtual void foo() {}
};
And let's say you create a heap-allocated object of a Derived
class and delete it using delete
keyword like:
int main()
{
Derived *d = new Derived();
delete d;
}
Compiling this code with -Wall -Wdelete-non-virtual-dtor -Werror
flags will throw you an error which is totally fine because it might eventually cause UB. Demo here.
Obviously, calling a destructor of d
object is what's causing the compiler error because following code has the same result (at least on CLANG, GCC has no problem with the following code):
int main()
{
Derived d;
d.~Derived();
}
But if I create a simple object on stack, there is no compiler errors for both CLANG and GCC:
int main()
{
Derived d;
}
We all know that Derived
class' destructor is being called at the end of main
function, but why there is no errors in such case?
When an object has automatic storage duration or is a member of a class, polymorphism need not be considered. In the code given, the lvalue d
cannot reference a more-derived object. Therefore, calling Derived::~Derived
is always correct and need not be warned about.