在创建新的a实例MyClass
作为函数的参数时,如下所示:
class MyClass
{
MyClass(int a);
};
myFunction(MyClass(42));
该标准是否对析构函数的时间做出任何保证?
具体来说,我可以假设它将在调用之后的下一个语句之前被调用myFunction()
吗?
Answers:
临时对象在它们所属的完整表达式的结尾处被销毁。
完整表达式是不是其他表达式的子表达式的表达式。通常,这意味着它在端部处;
(或)
为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的move语义会使它的用处不大。)
if(f(string())) { ... }
直到}
:)
(
和之间有一个完整的表达式,)
因为它们出现的语句无论如何都不是表达式。在您的解释中,end;
根本不会是full-expression-end,因为如果您在while / if或switch内,则它周围会有一个较大的“ expression”。我认为很容易看出这是没有道理的:)
每个人都正确地引用了12.2 / 3或类似的词,它回答了您的问题:
临时对象被销毁是评估(按词法)包含创建点的完整表达式的最后一步。
我发现在我打印该标准的下一页时,12.2 / 4说:
在两种情况下,临时变量在与完整表达式结束时不同的位置被销毁。
它们都不适用于您的示例,它们都与初始化器中的临时使用有关。但这确实表明,在处理像C ++标准这样的棘手野兽时,您必须保持智慧。
该标准确实提供了保证-从12.2 / 5节开始:
在函数调用(5.2.2)中与参考参数的临时绑定一直持续到包含该调用的完整表达式完成为止
但是,在代码中,不清楚是通过引用还是通过值传递参数,尽管有时会使用确实采用引用的复制构造函数。