Search code examples
c++destructorfinalvirtual-functions

Destructing stack object vs deleting heap-allocated object of non-final class with virtual functions


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?


Solution

  • 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.