【问题标题】:When does a unique_ptr returned by a function (via std::move) go out of scope函数(通过 std::move)返回的 unique_ptr 何时超出范围
【发布时间】:2021-05-06 20:37:21
【问题描述】:

我正在处理一个存储在共享内存区域中并由 getter 返回的大对象。由于对象的大小,我遇到了按值返回对象会破坏堆栈的问题。为了避免这种情况,我决定将unique_ptr 返回到堆上对象的副本,我希望调用函数能够将其用作局部变量。请参阅下面的示例代码:

注意:我正在处理的代码库是 C++11,而不是 C++14,所以我不能使用 std::make_unique

#include <memory>
struct AbsoluteUnit {
    char bigChungus[10000000];
    int bigChungusSize;
};
AbsoluteUnit g_absUnit;

std::unique_ptr<AbsoluteUnit> getAbsoluteUnit() {
    return std::move(std::unique_ptr<AbsoluteUnit>(new AbsoluteUnit(g_absUnit)));
}

void Example1()
{
    std::unique_ptr<AbsoluteUnit> absUnitPtr = getAbsoluteUnit();
    AbsoluteUnit& absUnit = *absUnitPtr.get();
    ///
    /// Some other code
    ///
}

void Example2()
{
    AbsoluteUnit& absUnit = *getAbsoluteUnit().get();
    ///
    /// Some other code
    ///
}

我的问题是:在 Example2 中,unique_ptr 何时超出范围?

在示例 1 中,我将 unique_ptr 存储在局部变量中,因此我希望它在函数退出时超出范围。但是在 Example2 中,我没有为它创建一个局部变量,那么在该行执行之后 unique_ptr 会发生什么?它是否仍然作用于函数,还是立即超出作用域?

【问题讨论】:

  • 顺便说一句,您应该删除返回的std::move。表达式 std::unique_ptr(...) 已经是一个 pr 值。添加std::move 将防止复制省略并使您的代码变慢。一个好的编译器应该对此提出警告。'
  • 感谢您的提示。我实际上看到此代码存在性能问题,所以这可能是原因。

标签: c++ c++11 scope unique-ptr


【解决方案1】:

get() 成员函数返回指向由std::unique_ptr&lt;AbsoluteUnit&gt; 管理的AbsoluteUnit 对象的指针,getAbsoluteUnit() 返回。

然后将托管的AbsoluteUnit 对象绑定到引用absUnit

AbsoluteUnit& absUnit = *getAbsoluteUnit().get();

但是,std::unique_ptr 在上述语句之后就不再存在,因此托管的AbsoluteUnit 对象也是如此。所以,absUnit 变成了一个悬空引用


如果你想避免使用指针语法,你可以改写:

const std::unique_ptr<AbsoluteUnit> ptr = getAbsoluteUnit();
AbsoluteUnit& obj = *ptr;
// ... use obj instead of ptr

或者更简洁的auto:

const auto ptr = getAbsoluteUnit();
auto& obj = *ptr;
// ... use obj instead of ptr

【讨论】:

  • 这就是我认为会发生的事情。 Example1 是我认为需要的,但我对 Example2 所做的单元测试通过了(在这种情况下这并不意味着太多)。
猜你喜欢
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
  • 2018-04-08
  • 1970-01-01
  • 2016-03-21
  • 2015-05-10
  • 2014-02-27
相关资源
最近更新 更多