【问题标题】:What is the scope of a unique_ptr returned from a function?从函数返回的 unique_ptr 的范围是什么?
【发布时间】:2011-05-23 13:20:50
【问题描述】:

这能正常工作吗? (见例子)

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?
}

【问题讨论】:

    标签: c++ unique-ptr


    【解决方案1】:

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

    在您的示例中,临时 unique_ptr 的生命周期以分号结束。 (所以是的,它会正常工作。)一般来说,当词法上包含其评估创建该临时对象的右值的完整表达式被完全评估时,临时对象将被销毁。

    【讨论】:

    • 那么函数doSomething是在unique_ptr被销毁之前执行的?
    • @tache:是的。对于任何返回值都是如此。如果它立即超出范围,则从函数返回 anything 将毫无用处。 :)
    • @tache:是的。顺序是 1.调用source 2.调用get 3.取消引用 4.调用doSomething 5.销毁临时unique_ptr
    • @jalf:但请注意,在调用 doSomething 函数时不使用 unique_ptr 本身。仅使用包含在 unique_ptr 中的原始指针。
    • 同样的逻辑仍然适用。临时持有返回值 必须在范围内停留足够长的时间才能使用,否则它将一文不值。正如其他评论者所说,您的代码非常安全
    【解决方案2】:

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

    【讨论】:

    • Microsoft:“作为表达式评估的结果创建的所有临时对象都在表达式语句的末尾(即分号)或 for 的控制表达式的末尾被销毁,如果、while、do 和 switch 语句。” msdn.microsoft.com/en-us/library/a8kfxa78(v=VS.100).aspx
    • @tache 请参阅 C++03 标准中的 1.9/12 和 12.2/3 以获得明确的答案。
    • @tache:不是免费的(但很好的投资,恕我直言)。谷歌一下,你会发现一些委员会的草案非常接近官方版本。
    • 经过长时间的搜索,我发现:“C++0x 标准的最终委员会草案 (FCD)”open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf
    • 没有好的例子虽然很难知道它们的确切含义。所以我认为本文档仅适用于 C++ 大师。
    【解决方案3】:

    应该没问题。考虑

    int Func()
    {
      int ret = 5;
    
      return ret;
    }
    
    void doSomething(int a) { ... }
    
    
    doSomething(Func());
    

    即使您在堆栈上返回 ret 也没关系,因为它在调用范围内。

    【讨论】:

    • 但是 Func() 无论如何都会返回 ret 的副本。所以我认为这个例子并不相关。
    猜你喜欢
    • 1970-01-01
    • 2011-05-18
    • 2021-05-06
    • 2015-02-24
    • 2012-08-20
    相关资源
    最近更新 更多