Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The state of an object between a call to ~Derived() and ~Base()

Question

What does the C++ standard guarantee about the state of an object in the time after a derived class's destructor executes, but before the base class's destructor executes ? (This is the time when the derived class's subobjects' destructors are being called.)

Example

#include <string>
struct Base;

struct Member {
  Member(Base *b);
  ~Member();
  Base *b_;
};

struct Base {
  virtual void f() {}
  virtual ~Base() {}
};

struct Derived : Base {
  Derived() : m(this) {}
  virtual ~Derived() {}  
  virtual void f() {}
  std::string s; 
  Member m;
};

Member::Member(Base *b) : b_(b) {}
Member::~Member() {
  // At this point, ~Derived has finished -- can we use b_ as a 
  // Derived* object (i.e. call Derived::f or access Derived::s)?
  b_->f();
}

int main() {
  Base *bd = new Derived;
  delete bd;
}

In this example, a Member object has a pointer to a Derived object that owns it, and it attempts to access that Derived object as it is destructed...even though the destructor for Derived has already finished.

Which version of *bd's virtual functions would be called if some subobject called a virtual function after ~Derived() executes, but before ~Base() executes? Is it even legal to access *bd when it's in that state?

like image 560
Nate Kohl Avatar asked Jun 27 '12 21:06

Nate Kohl


1 Answers

For me, from [12.4] it clearly stands, that it is not legal:

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8). [Example: ...]

Despite the lack of definition for no longer exists, I think, I can say that referencing an object which no longer exists results in undefined behaviour.

like image 98
Rafał Rawicki Avatar answered Sep 18 '22 10:09

Rafał Rawicki