【问题标题】:Reason of additional destructor call?额外的析构函数调用的原因?
【发布时间】:2021-08-03 06:22:37
【问题描述】:

给出以下简单类:

#include <iostream>

class Foo{
    int a, b;
    public:
        Foo(int _a = 0, int _b = 0) : a(_a), b(_b) { 
            std::cout << "Foo(int, int)" << "\n"; 
        }

        Foo(const Foo& foo) : a(foo.a), b(foo.b) { 
            std::cout << "Foo(const Foo&)" << "\n"; 
        }

        Foo& operator=(const Foo& other) { 
            std::cout << "operator=(const Foo&)" << "\n"; 
            if(this != &other){
                a = other.a; 
                b = other.b;
            }
            return *this; 
        }

        ~Foo() { 
            std::cout << "~Foo()" << "\n"; 
        }

        Foo operator+(const Foo& other){
            std::cout << "foo.operator+(const Foo&)" << "\n";
            return Foo(a + other.a, b + other.b);
        }
};

还有主要的:

int main(){
    Foo f1, f2(1, 2), f3;
    std::cout << "-----------" << "\n";
    f3 = f1 + f2;                          // (*)
    std::cout << "-----------" << "\n";
    return 0;
}

我使用-std=c++11 编译,出于演示目的还使用-fno-elide-constructors 标志。输出内容为:

Foo(int, int)
Foo(int, int)
Foo(int, int)
-----------
foo.operator+(const Foo&) // (1)
Foo(int, int)             // (2)
Foo(const Foo&)           // (3)
~Foo()                    // (4)
operator=(const Foo&)     // (5)
~Foo()                    // (6)
-----------
~Foo()
~Foo()
~Foo()

据我正确理解,f3 = f1 + f2; (*) 行发生以下情况:

  1. 显然,f1.operator+(f2) 被调用。
  2. 创建了一个新的(临时)对象。让我们用T来表示它。
  3. 由于operator+() 函数不返回引用,我们调用复制构造函数来构造T2T 的副本。我们返回T2
  4. 调用析构函数来删除临时对象T
  5. 我们调用复制赋值运算符将T2的所有成员分配给f3

我的问题:我真的不明白 (6) 的目的是什么。为什么要额外调用析构函数,即我在这里遗漏了什么?

【问题讨论】:

  • 如果您在输出消息中包含this 的值,这将有助于您的调试/理解。然后你会看到在哪些对象实例上调用了哪些操作
  • 临时的T2也需要被销毁。那是 (6)。
  • 我数了 5 个构造函数和 5 个析构函数。 (在我的机器上,-O3,我有 4 和 4。)我不确定你为什么认为有一个“额外的”析构函数调用。
  • 我已经制作了一个用 ID 标记对象的对象,因此很明显正在构造/破坏什么并且更清楚:godbolt.org/z/jfd9fj9eo 有趣的是,gcc 11 只生成 4 个对象(它们都是破坏) - 看看:godbolt.org/z/aTa6hGE44

标签: c++ destructor


【解决方案1】:

我在这里错过了什么?

T2的破坏。

调用了3+2个构造函数,也调用了3+2个析构函数!

【讨论】:

  • 该死,我不敢相信我错过了这个。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多