类析构函数被调用两次

时间:2014-12-29 18:32:23

标签: c++ class visual-c++ scope destructor

我有以下程序:

#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;
}

打印以下内容:

Print screen

为什么~A()被调用两次?

1 个答案:

答案 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对象。