一个函数返回的unique_ptr的作用域是什么?

12

这个方法是否能正常工作?(参见示例)

unique_ptr<A> source()
{
    return unique_ptr<A>(new A);
}


void doSomething(A &a)  
{  
    // ...
}  

void test()  
{  
    doSomething(*source().get());   // unsafe?
    // When does the returned unique_ptr go out of scope?
}
3个回答

21

从函数返回的unique_ptr没有作用域,因为作用域仅适用于名称。

在您的示例中,临时unique_ptr的生存期在分号处结束。(所以是的,它会正常工作。)通常,当完全评估了包含创建该临时对象的rvalue的词法全表达式时,临时对象将被销毁。


那么在unique_ptr被销毁之前,函数doSomething会被执行吗? - tache
2
@tache:是的。对于任何返回值都是如此。如果它立即超出范围,从函数返回任何东西都将相当无用。 :) - jalf
1
@tache:是的。顺序是1. 调用source 2. 调用get 3. 解引用 4. 调用doSomething 5. 销毁临时的unique_ptr - fredoverflow
@jalf: 但请注意,unique_ptr本身并没有在调用函数doSomething时使用.. 只有包含在unique_ptr中的原始指针被使用。 - tache
2
相同的逻辑仍然适用。暂时持有返回值的变量必须在作用域内保持足够长的时间以便使用,否则它将毫无价值。正如其他评论者所说,您的代码是完全安全的。 - jalf

5

临时值在评估“完整表达式”后被销毁,该表达式(粗略地)是最大的封闭表达式 - 或者在这种情况下,是整个语句。因此是安全的;unique_ptr在doSomething返回后被销毁。


微软:“由表达式计算产生的所有临时变量都会在表达式语句结束时(即分号处)或for、if、while、do和switch语句的控制表达式结束时被销毁。” http://msdn.microsoft.com/en-us/library/a8kfxa78(v=VS.100).aspx - tache
1
@tache请参考C++03标准中的1.9/12和12.2/3,以获取明确的答案。 - Alan Stokes
1
@tache:不是免费的(但我认为这是一个很好的投资)。通过一些谷歌搜索,你可以找到一些委员会草案,它们非常接近官方版本。 - Alan Stokes
经过长时间的搜索,我找到了这个:C++0x标准的最终委员会草案(FCD)http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf - tache
没有好的例子,很难确切地知道它们的含义。因此,我认为这份文档只适合C++大师。 - tache

1

应该没问题。考虑一下

int Func()
{
  int ret = 5;

  return ret;
}

void doSomething(int a) { ... }


doSomething(Func());

尽管你在堆栈上返回ret,但由于它在调用范围内,所以这是可以的。


1
但是无论如何,Func()会返回ret的一个副本。所以我认为这个例子并不是很相关。 - tache

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接