Very similar question as these, except not exactly: What is the order in which the destructors and the constructors are called in C++
Order of member constructor and destructor calls
I want to know: are the member variables of the derived class destroyed before or after the destructor of the base class is called?
This is in C++ using Visual Studio 2008. Thanks.
constructor: first base, then derived
destruction:
- ~derived
- ~member derived
- ~base
- ~member base
code:
class member {
string s;
public:
member(string s) {
this-> s = s;
}
~member() {
cout << "~member " << s << endl;
}
};
class base {
member m;
public:
base() : m("base"){
}
~base() {
cout << "~base" << endl;
}
};
class derived : base{
member m2;
public:
derived() :m2("derived") { }
~derived() {
cout << "~derived" << endl;
}
};
int main(int argc, const char * argv[]) {
derived s;
return 0;
}
References & virtual destructor
When you plan to dynamically allocate (i.e. when you use the keywords new
& delete
) a derived object, then always have a virtual
or a protected
destructor on your base. Dynamically deleting the object on the base class reference would otherwise lead to memory leaks in the example below:
class base {
member m;
public:
base() : m("base"){
}
/* correct behaviour is when you add **virtual** in front of the signature */
~base() {
cout << "~base" << endl;
}
};
class derived : public base{
member m2;
char* longArray;
public:
derived() :m2("derived") {
longArray = new char[1000];
}
~derived() {
delete[] longArray; // never called
cout << "~derived" << endl;
}
};
int main(int argc, const char * argv[]) {
base *s = new derived; // mind the downcast to **base**
delete s; /* only the non-virtual destructor on the base and its members is called.
No destructor on derived or its members is called.
What happens to the memory allocated by derived?
**longArray** is leaked forever.
Even without **longArray**, it most probably **leaks** memory, as C++ doesn't define its behaviour
*/
return 0;
}
Output:
Only base data is cleaned up, and longArray
leaks.
Here's what the standard says... (C++11, 12.4/8)
After executing the body of the destructor and destroying any automatic objects allocated within the body, a
destructor for class X
calls the destructors for X
’s direct non-variant non-static data members, the destructors
for X
’s direct base classes and, if X
is the type of the most derived class (12.6.2), its destructor calls the
destructors for X
’s virtual base classes. All destructors are called as if they were referenced with a qualified
name, that is, ignoring any possible virtual overriding destructors in more derived classes. Bases and
members are destroyed in the reverse order of the completion of their constructor (see 12.6.2). A return
statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the
caller, the destructors for the members and bases are called. Destructors for elements of an array are called
in reverse order of their construction (see 12.6).
Note that this order is indeed the reverse of the order given in 12.6.2/10 in C++11. You can't tell what the order of destruction of virtual bases is from looking at 12.4/8 alone, but you can infer it from 12.6.2/10, which specifies that initialization of virtual bases occurs in depth-first search left-to-right order. (Thus, destruction of virtual bases occurs in the reverse of that order.)
Anyway, you have your answer. Non-static members are destroyed first, then base classes. But a base class's members will be destroyed before the next base class's destructor starts. It really is exactly like depth-first search.