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.)
#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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With