【发布时间】: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; (*) 行发生以下情况:
- 显然,
f1.operator+(f2)被调用。 - 创建了一个新的(临时)对象。让我们用
T来表示它。 - 由于
operator+()函数不返回引用,我们调用复制构造函数来构造T2的T的副本。我们返回T2。 - 调用析构函数来删除临时对象
T。 - 我们调用复制赋值运算符将
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