Search code examples
c++virtual-destructor

Why missing virtual d-tor in g++ does not destroy stack allocated members of derived class?


I have the following code:

struct Message
{
   explicit Message(const std::string& message) : selfMessage(message) {};
   ~Message() { std::cerr << "Message: " << selfMessage << std::endl; }
   const std::string selfMessage;
};

struct Foo
{
   Foo() : fooMessage("Foo") {}
   /// Destructor here is left intentionally non-virtual !!!
   ~Foo() { std::cerr << "~Foo" << std::endl; }

   Message fooMessage;
};

struct Bar : Foo
{
   Bar() : barMessage("Bar") {}
   ~Bar() { std::cerr << "~Bar" << std::endl; }
   Message barMessage;
};

int main()
{
  std::auto_ptr<Foo> foo(new Bar);
}

I expect the following output:

Message: Bar
Message: Foo
~Foo()

But actually (the code is compiled with gcc) does not print Message: Bar so as far as I understand barMessage is not destructed correctly. Why?

AFAIK non virtual d-tor affects only on the call of dtor of derived class - it will be never called, but what about stack-allocated members of derived class?

Thank you,

P.S. I already know about deprecated std::auto_ptr<>() usage :)


Solution

  • If you call delete on a derived object through a pointer to a base class object then you get undefined behavior unless the destructor of the base class is declared virtual.

    Letting an std::auto_ptr templated on a base class go out of scope when it owns a derived class object has the effect of calling delete on a base class pointer type when the actual object is of a derived class type.