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.
Destructors for virtual base classes are called in the reverse order of declaration.
The destructor for a class object is called before destructors for members and bases are called. Destructors for nonstatic members are called before destructors for base classes are called.
Class E (member object 1) destructor is called and finishes. Class C (base of F) destructor is called and finishes.
Destructors are called automatically when a variable goes out of scope. Because the base class destructor is inherited, and because the derived class object "is" a base class object, both the derived class destructor (even if it is the "default" destructor) and the base class destructor are called automatically.
In single inheritance, firstly, Child class destructors are called and then the parent class destructors are called. Let’s see the invocation of constructors and Destructors in Single inheritance in C++. The derived class constructor called second.
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).
The sequence of invocation of constructors and Destructors in C++ is different in different situations. Let’s see them one by one. Let’s see the order of invocation of constructors and Destructors in C++ having a simple Class. First: T4Tutorials class constructor. Second: T4Tutorials class destructor.
Destructors for nonstatic member objects are called in the reverse order in which they appear in the class declaration. The optional member initialization list used in construction of these members does not affect the order of construction or destruction. Destructors for non-virtual base classes are called in the reverse order of declaration.
constructor: first base, then derived
destruction:
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;
}
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 forX
’s direct non-variant non-static data members, the destructors forX
’s direct base classes and, ifX
is the type of the most derived class (12.6.2), its destructor calls the destructors forX
’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.
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