当创建MyClass
的新实例作为这样的函数的参数时:
class MyClass
{
MyClass(int a);
};
myFunction(MyClass(42));
该标准是否对破坏者的时间安排任何受助者?
具体来说,我可以假设在调用myFunction()
后的下一个语句之前调用它吗?
答案 0 :(得分:97)
临时对象在它们所属的完整表达式的末尾被销毁。
完整表达式是一个表达式,它不是某个其他表达式的子表达式。通常这意味着它以;
(或)
if
,while
,switch
等)结束,表示声明的结束。在您的示例中,它是函数调用的结束。
请注意,您可以通过将临时值绑定到const
引用来延长临时值的生命周期。这样做会将其生命周期延长到参考的生命周期:
MyClass getMyClass();
{
const MyClass& r = getMyClass(); // full expression ends here
...
} // object returned by getMyClass() is destroyed here
如果您不打算更改返回的对象,那么这是保存复制构造函数调用(与MyClass obj = getMyClass();
相比)的一个很好的技巧,以防未应用返回值优化。不幸的是,它并不是很有名。 (我认为C ++ 11的移动语义会降低它的用处。)
答案 1 :(得分:23)
每个人都正确地引用了12.2 / 3或类似的内容,它们回答了您的问题:
临时对象被破坏了 评估的最后一步 完全表达(词汇) 包含他们所处的位置 创建
我觉得在我的标准打印中在下一页上很有意思,12.2 / 4说:
有两种情况 临时的人被摧毁了 不同点比结束了 全表达。
它们都不适用于您的示例,它们都与初始化程序中临时使用有关。但它确实表明你在处理像C ++标准这样棘手的野兽时必须保持你的智慧。
答案 2 :(得分:10)
该标准确实提供了保证 - 来自第12.2 / 5节:
临时绑定到引用 函数调用中的参数(5.2.2) 一直持续到完成 包含调用的完整表达式
但是,在您的代码中,不清楚参数是通过引用还是通过值传递,尽管在某些时候将使用引用引用的复制构造函数。
答案 3 :(得分:3)
在第12.2节“临时对象”第3节中,ANSI / ISO C标准声明:“...作为评估全表达式的最后一步,(词法上)包含创建它们的点,临时对象被销毁。“
这与Sequence Points的概念密切相关。达到序列点时,保证表达式的所有副作用都已发生。