Reputation: 26281
I have the following program:
#include<iostream>
using namespace std;
class A {
protected:
A() { cout << "Executing A()" << endl; }
public:
~A() { cout << "Executing ~A()" << endl; }
};
class B : public A {
public:
B() { cout << "Executing B()" << endl; }
~B() { cout << "Executing ~B()" << endl; }
};
class C : public B {
public:
C() { cout << "Executing C()" << endl; }
~C() { cout << "Executing ~C()" << endl; }
};
void someFunc() {
A a = C();
}
int main() {
someFunc();
return 0;
}
which prints the following:
Why is ~A()
called twice?
Upvotes: 1
Views: 120
Reputation:
The destructor for A
is called twice because there are two objects that need to be destroyed. By printing something when the copy or move constructor is called you can verify this:
class A { protected: A() { cout << "Executing A()" << endl; } public: A(const A &) { cout << "Executing A(const A &)" << endl; } // with recent compilers, you could also try A(A &&) ~A() { cout << "Executing ~A()" << endl; } };
Output:
Executing A() Executing B() Executing C() Executing A(const A &) Executing ~C() Executing ~B() Executing ~A() Executing ~A()
Basically, A a = C();
doesn't do what you might think it does. It creates an anonymous C
object, and then creates a
as an A
object, copying from the just-created anonymous object. It does not let a
somehow point to a real C
object.
A variable declared as A
is always an A
, never any derived type. To get something to that effect, you would need to use pointers or references.
const A &a = C();
Here, a
is not an A
object. This creates the same anonymous C
object as before, but then makes a
a reference to that anonymous object, instead of attempting to create a new A
object.
Upvotes: 5