类析构函数被调用两次

Mat*_*ero 0 c++ destructor scope class visual-c++

我有以下程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

其中打印以下内容:

打印屏幕

为什么~A()叫两次?

小智 5

析构函数for A被调用两次,因为有两个对象需要被销毁.通过在调用复制或移动构造函数时打印某些内容,您可以验证以下内容:

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; }
};
Run Code Online (Sandbox Code Playgroud)

输出:

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();
Run Code Online (Sandbox Code Playgroud)

在这里,a不是一个A对象.这将创建与C以前相同的匿名对象,但随后会a引用该匿名对象,而不是尝试创建新A对象.