【问题标题】:Why is the destructor being called three times?为什么析构函数被调用了 3 次?
【发布时间】:2013-11-24 04:21:13
【问题描述】:

输入:

#include <iostream>
using namespace std;
class SimpleClass
{
    public:

    SimpleClass()
    {
        cout<<"SimpleClass Constructor\n";
    }
    virtual ~SimpleClass()
    {
        cout<<"SimpleClass destructor\n";
    }
};
int main()
{
    SimpleClass a;    
    SimpleClass lol = a;

    SimpleClass b;
    SimpleClass * lol2 = &b;
}

输出:

SimpleClass Constructor
SimpleClass Constructor
SimpleClass destructor
SimpleClass destructor
SimpleClass destructor

我很困惑为什么要调用 3 次析构函数。

构造函数只被调用了两次!!!

【问题讨论】:

  • 你有 3 个对象,对吧? a, lol, b。您期望多少次析构函数调用?如果你实现copy constructor,你会看到一个对象被复制了。
  • 您预期的次数是多少?
  • 我预计是 2 次。因为lol构造函数没有被调用。
  • 问题应该是“为什么只有 2 次构造函数调用?”
  • @mk1 不,复制构造函数是为lol调用的。

标签: c++ constructor destructor


【解决方案1】:

析构函数被调用了 3 次,分别是 alolb
在您的情况下,ab 使用 default constructor 实例化。但是请注意,lol 是使用 copy constructor 实例化的

【讨论】:

    【解决方案2】:

    因为恰好创建了 3 个 SimpleClass 类的对象,但你的构造函数只被调用了 2 次:

    • 第一个对象是a,调用你的构造函数;
    • 第二个是lol,通过隐式定义的复制构造函数a复制初始化(从而绕过你的构造函数);
    • 第三个是b,调用你的构造函数。

    请注意,lol2 只是一个指向 b 的指针,因此不会进行额外的调用。

    正确的名称是“析构函数”,而不是“解构函数”;)

    【讨论】:

    • 你能重载这个隐式定义的复制构造函数吗?
    • 是的,您可以将其显式定义为 SimpleClass(const SimpleClass& other)。但是这里有一个警告:允许编译器在安全的情况下优化调用。这就是为什么复制构造函数通常不应该有任何副作用(写入 cout 是一个副作用)。如果您的复制构造函数没有输出任何内容,请关闭编译器优化。
    • @AlexJenter:但是如果复制构造函数调用被优化掉(在这种情况下不会),析构函数也会被优化,所以构造函数调用仍然 == 析构函数调用。跨度>
    • @Benjamin Lindley:没错,感谢您的有用补充。我并不是说它会在这个例子中进行优化,这是一个普遍的警告,这是可能的。
    【解决方案3】:

    您有 3 个对象 alolb。您没有跟踪编译器生成的复制构造函数(这个由lol 调用),所以这就是为什么只有两个构造函数。

    【讨论】:

      【解决方案4】:

      alolb 分别调用一次。

      要确认这一点,您可以在类中添加一个字段,并为每个类分配一个名称/ID,然后在析构函数中打印出来。您还可以打印出this 的值,它是一个指向对象的指针。

      【讨论】:

        【解决方案5】:
          SimpleClass lol = a;    //calls the default copy constructor which you have not defined
        

        覆盖复制构造函数,然后你可能会看到一个新的构造函数被调用。

        【讨论】:

          【解决方案6】:

          你有alolb

          也许你可以在main() 以及构造函数和析构函数中打印它们的地址,然后你会看到它。

          【讨论】:

            【解决方案7】:

            因为所有对象的析构函数都是一样的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-01-12
              • 1970-01-01
              • 2021-11-06
              • 1970-01-01
              • 2015-07-26
              • 2013-12-11
              相关资源
              最近更新 更多