我有以下程序:
#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;
}
打印以下内容:
为什么~A()
被调用两次?
答案 0 :(得分:5)
A
的析构函数被调用两次,因为有两个对象需要被销毁。 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; } };
输出:
Executing A() Executing B() Executing C() Executing A(const A &) Executing ~C() Executing ~B() Executing ~A() Executing ~A()
基本上,A a = C();
并没有做你认为它做的事情。它创建一个匿名C
对象,然后创建a
作为A
对象,从刚刚创建的匿名对象进行复制。它不会让a
以某种方式指向真正的C
对象。
声明为A
的变量总是 A
,永远不是任何派生类型。要获得相应的效果,您需要使用指针或引用。
const A &a = C();
此处,a
不 A
个对象。这将创建与以前相同的匿名C
对象,但随后使a
成为对该匿名对象的引用,而不是尝试创建新的A
对象。