何时销毁默认参数对象?

时间:2013-01-13 23:50:24

标签: c++ destructor

void foo(const Object & o = Object()) {
      return;
}

在上面的函数中,什么时候〜应该调用对象?当函数退出时或者在调用站点周围的块的末尾?

3 个答案:

答案 0 :(得分:9)

默认参数将在包含函数调用的完整表达式的末尾被销毁。

答案 1 :(得分:6)

详细说明 David 所说的内容,该标准在 12.2 [class.temporary] 部分中说明:

  

有两种情况下,临时状态被摧毁   不同于完整表达的结束点。 [...] 第二   context是指引用绑定到临时的。临时到   哪个引用绑定或临时是完整的   绑定引用的子对象的对象仍然存在   参考的有效期除外:

     
      
  • ...
  •   
  • 函数调用(5.2.2)中的引用参数的临时绑定将持续到完整表达式完成   包含电话。
  •   
  • ...
  •   

因此,当函数退出时,或者当包含调用的块结束时,它们既不会被破坏,而是在包含函数调用的完整语句的末尾(简单地说,在函数调用后的第一个分号处,在调用中)上下文)。

编辑:所以说我们得到了:

int foo(const Object & o = Object());

some_stuff();    
std::cout << (foo() + 7);
other_stuff();

这大致相当于以下(注意概念范围块):

some_stuff(); 
{
    Object o;             // create temprorary
    int i = foo(o);       // and use it
    int j = i + 7;        // do other things
    std::cout << j;       // while o still alive
}                         // finally destroy o
other_stuff();

编辑:正如 Michael 在评论中指出的那样,我给出的“声明/分号” -analogy是一个简化的术语“完整表达”并且有些情况会有点不同,例如他的例子:

if(foo()) bar();

在调用bar之前会破坏临时值,因此与表达式语句不同:

foo() ? bar() : 0;

但是,“分号” -analogy通常是一个很好的选择,即使完整表达式不一定与语句(可以包含多个完整表达式)相同。

答案 2 :(得分:0)

我认为这段代码不应该编译。除非是const,否则不能将引用绑定到临时引用。如果它是const,则临时应保持活动直到函数表达式结束。与其中定义的局部变量相同。