【发布时间】:2014-11-28 20:59:42
【问题描述】:
我很确定,函数参数的析构函数应该在相应函数的出口处调用。考虑 C++11 标准的 5.2.2p4:
[...] 参数的生命周期在定义它的函数返回时结束。 [...]
不过,让我们试试这段代码:
#include <iostream>
using namespace std;
struct Logger {
Logger(int) { cout << "Construct " << this << '\n'; }
Logger(const Logger&) { cout << "Copy construct " << this << '\n'; }
~Logger() { cout << "Destruct " << this << '\n'; }
};
int f(Logger)
{
cout << "Inside f\n";
return 0;
}
int main()
{
f(f(f(10)));
}
用gcc或clang编译后,输出如下:
Construct 0x7fffa42d97ff
Inside f
Construct 0x7fffa42d97fe
Inside f
Construct 0x7fffa42d97fd
Inside f
Destruct 0x7fffa42d97fd
Destruct 0x7fffa42d97fe
Destruct 0x7fffa42d97ff
正如我们所见,所有三个参数仅在最后一个函数调用完成后才被销毁。这是正确的行为吗?
【问题讨论】:
-
另一个问题的总结:您阅读标准是完全正确的,但标准并没有正确反映意图,意图也是允许您的编译器的行为。跨度>
-
“我们可以看到,所有三个参数都是在最后一次函数调用完成后才被销毁的。” 我们看不到这样的事情。我确定你误解了这个输出。
-
@LokiAstari That other question 一开始就不应该关闭,但即使关闭了,那又有什么区别呢?无论如何,它确实提出了同样的问题,并且那里的答案确实为这个问题提供了答案。
-
@hvd:不,允许复制省略以消除这种副作用。是的,在
main中构建了绝对临时的。文字10(以及每个调用的返回值)用于构造一个值以复制到f的参数中。如果只有 OP 引用了 整个 段落。 -
@dyp 是编译器不符合C++11的领域,but the standard is being changed to allow the compilers' behaviour。
标签: c++