在类成员中正确使用unique_ptr

Sae*_*ani 1 c++ unique-ptr c++11 c++14

我正在尝试真正从c ++ 98迁移到c ++ 11及更高版本。我已经把大部分新东西都包裹在头上了,但是我仍然不确定正确的用法unique_ptr

考虑下面的示例,其中类A有一个unique_ptr成员(我以前曾经用过裸指针!)。当用户需要时,可以通过在其他地方(不是类的一部分)调用函数来分配此成员变量。这是正确的用法吗?如果没有,最好的选择是什么?

class A {
private:
   unique_ptr<MyType> mt;
public:
   void initStuff() {
      mt.reset(std::move(StaticFuncSomewhereElese::generateMyType()));
   } 
};

MyType* StaticFuncSomewhereElese::generateMyType() {
    MyType* temp = new MyType(...);
    //do stuff to temp (read file or something...)
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

eml*_*lai 5

您的代码可以正常工作(尽管move可以省略冗余* ),但最好unique_ptr尽早构建:

class A {
private:
   std::unique_ptr<MyType> mt;
public:
   void initStuff() {
      mt = StaticFuncSomewhereElese::generateMyType();
   } 
};

std::unique_ptr<MyType> StaticFuncSomewhereElese::generateMyType() {
    auto temp = std::make_unique<MyType>(…);
    // `make_unique` is C++14 (although trivially implementable in C++11).
    // Here's an alternative without `make_unique`:
    // std::unique_ptr<MyType> temp(new MyType(…));

    //do stuff to temp (read file or something...)
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

这样很明显,generateMyType调用者必须删除的返回值,并且内存泄漏的可能性较小(例如,如果generateMyType提早返回)。

* move是多余的,因为:

  1. 原始指针无法移动。
  2. generateMyType()无论如何,表达式的结果已经是右值。

  • 注意,这个问题被标记为C ++ 11,因此值得一提的是直到C ++ 14才引入`std :: make_unique`。 (3认同)

eer*_*ika 5

这是正确的用法吗?

除了std::move多余之外,是的,这是正确的。它是多余的,因为a)裸指针被复制,无论它们是左值还是右值,b)函数不返回引用,因此返回值已经是右值,因此不需要转换。

但仍有改进的空间。特别是,我建议从工厂函数返回一个唯一的指针:

std::unique_ptr<MyType> StaticFuncSomewhereElese::generateMyType()
Run Code Online (Sandbox Code Playgroud)

如果初始化抛出异常,这可以防止temp泄漏,并使工厂的用户更难意外泄漏返回的指针。