C ++:临时论证的生命周期?

时间:2010-03-24 10:18:56

标签: c++ destructor

当创建MyClass的新实例作为这样的函数的参数时:

class MyClass
{
  MyClass(int a);
};    

myFunction(MyClass(42));

该标准是否对破坏者的时间安排任何受助者?
具体来说,我可以假设在调用myFunction()后的下一个语句之前调用它吗?

4 个答案:

答案 0 :(得分:97)

临时对象在它们所属的完整表达式的末尾被销毁。

完整表达式是一个表达式,它不是某个其他表达式的子表达式。通常这意味着它以;(或) ifwhileswitch等)结束,表示声明的结束。在您的示例中,它是函数调用的结束。

请注意,您可以通过将临时值绑定到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的概念密切相关。达到序列点时,保证表达式的所有副作用都已发生。