簡體   English   中英

在類成員中正確使用unique_ptr

[英]Correct usage of unique_ptr in class member

我正在嘗試真正從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;
}

您的代碼工作正常(盡管可以省略多余的* 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;
}

這樣很明顯,調用者必須刪除generateMyType的返回值,並且內存泄漏的可能性較小(例如,如果generateMyType提前返回)。

* move是多余的,因為:

  1. 原始指針無法移動。
  2. 無論如何, generateMyType()表達式的結果已經是右值。

這是正確的用法嗎?

除了std::move是多余的,是的,這是正確的。 這是多余的,因為a)復制裸指針,無論它們是左值還是右值,並且b)該函數不返回引用,因此返回值已經是右值,因此無需進行轉換。

但是還有改進的空間。 特別是,我建議從工廠函數返回唯一的指針:

std::unique_ptr<MyType> StaticFuncSomewhereElese::generateMyType()

如果初始化引發異常,這可以防止temp泄漏,並使工廠用戶更難於意外泄漏返回的指針。

為什么不將其設為通用模板工廠?

在標題中。

template <typename T>
std::unique_ptr<T> generateMyType();

classss A {
private:
   std::unique_ptr<MyType> mt;
   std::unique_ptr<MyOtherType> mot;
public:
   void initStuff() {
      mt = generateMyType<MyType>();
      mot = generateMyType<MyOtherType>();
   } 
};

並在源文件中

template <typename T>
std::unique_ptr<T> generateMyType()
{
  auto temp = std::make_unique<T>();
  return temp;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM