【问题标题】:Class destructor is being called twice类析构函数被调用两次
【发布时间】:2015-02-25 22:46:09
【问题描述】:

我有以下程序:

#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() 被调用了两次?

【问题讨论】:

  • 您的赋值可能会触发复制构造函数(当您将 C() 分配给 a 但您的输出代码对此(或赋值运算符)不可见。请参阅 en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29
  • @Mati:不要使用图像粘贴纯文本。只需粘贴纯文本即可。
  • @Deduplicator 很高兴知道!

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


【解决方案1】:

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

输出:

执行 A()
执行 B()
执行 C()
执行 A(const A &)
执行 ~C()
执行 ~B()
执行 ~A()
执行~A()

基本上,A a = C(); 不会像您认为的那样做。它创建一个匿名C 对象,然后创建a 作为A 对象,从刚刚创建的匿名对象中复制。它不会让a 以某种方式指向一个真实的C 对象。

声明为A 的变量始终A,绝不是任何派生类型。要达到这种效果,您需要使用指针或引用。

const A &a = C();

这里,a 不是 A 对象。这将创建与以前相同的匿名 C 对象,但随后使 a 成为对该匿名对象的引用,而不是尝试创建新的 A 对象。

【讨论】:

  • 从技术上讲,原始代码应该调用一个移动:)
  • 如何避免这种临时对象的创建?如何使AC 成为同一个对象? (同一地址)
  • @T.C.假设一个符合 C++11 的实现(或更新),你是对的。
  • 相信你想要A&amp; a = C();
  • @Havenard 关闭。 const A&amp; a = C(); 是有效的,A&amp;&amp; a = C(); 也是有效的(从 C++11 开始),但不是 A&amp; a = C();。现在编辑成我的答案。
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 2011-02-07
  • 2017-11-03
  • 2013-12-11
  • 2021-11-06
  • 1970-01-01
相关资源
最近更新 更多