简体   繁体   English

如何正确地将所有权从原始指针移动到std :: unique_ptr?

[英]How to correctly move ownership from raw pointer to std::unique_ptr?

My approach is: 我的方法是:

class SomeClass
{
    std::vector<std::unique_ptr<MyObject>> myObjects;
public:
    void takeOwnership(MyObject *nowItsReallyMyObject)
    {
        myObjects.emplace_back(std::move(nowItsReallyMyObject));
    }
};

Am I doing everything correctly or are there any better solutions? 我是在正确地做所有事情还是有更好的解决方案?

The move is redundant. move是多余的。

Myself, I'd do this: 我自己,我会这样做:

void takeOwnership(std::unique_ptr<MyObject> nowItsReallyMyObject)
{
    myObjects.emplace_back(std::move(nowItsReallyMyObject));
}

because I would want to move the unique_ptr ownership semantics as far "out" as possible. 因为我希望将unique_ptr所有权语义尽可能地“移出”。

I might write this utility function: 我可能会写这个效用函数:

template<class T>
std::unique_ptr<T> wrap_in_unique( T* t ) {
  return std::unique_ptr<T>(t);
}

so callers can: 所以来电者可以:

foo.takeOwnership(wrap_in_unique(some_ptr));

but even better, then can push the borders of unique_ptr semantics out as far as they reasonably can. 但更好的是,可以将unique_ptr语义的边界推到合理的范围内。

I might even do: 我甚至可以这样做:

template<class T>
std::unique_ptr<T> wrap_in_unique( T*&& t ) {
  auto* tmp = t;
  t = 0;
  return std::unique_ptr<T>(tmp);
}
template<class T>
std::unique_ptr<T> wrap_in_unique( std::unique_ptr<T> t ) {
  return std::move(t);
}

which lets callers transition their T* into unique_ptr s easier. 这让调用者可以更轻松地将他们的T*转换为unique_ptr All of their T* -> unique_ptr<T> is now wrapped in a std::move , and zeros the source pointer. 它们的所有T* - > unique_ptr<T>现在都包含在std::move ,并将源指针归零。

So if they had 所以,如果有的话

struct I_am_legacy {
  T* I_own_this = 0;
  void GiveMyStuffTo( SomeClass& sc ) {
    sc.takeOwnership( wrap_in_unique(std::move(I_own_this)) );
  }
};

the code can be transformed into: 代码可以转换为:

struct I_am_legacy {
  std::unique_ptr<T> I_own_this;
  void GiveMyStuffTo( SomeClass& sc ) {
    sc.takeOwnership( wrap_in_unique(std::move(I_own_this)) );
  }
};

and it still compiles and works the same. 它仍然编译和工作相同。 (Other interaction with I_own_this may have to change, but part of it will already be unique_ptr compatible). (与I_own_this其他交互可能必须改变,但其中一部分已经与unique_ptr兼容)。

You should accept the unique_ptr from the get-go: 你应该从一开始就接受unique_ptr

class SomeClass
{
    std::vector<std::unique_ptr<MyObject>> myObjects;
public:
    // tells the world you 0wNz this object
    void takeOwnership(std::unique_ptr<MyObject> myObject)
    {
        myObjects.push_back(std::move(myObject));
    }
};

This way you make it clear you take ownership and you also help other programmers to avoid using raw pointers. 通过这种方式,您可以清楚地了解所有权,还可以帮助其他程序员避免使用原始指针。

Further reading: CppCoreGuidelines R.32 进一步阅读: CppCoreGuidelines R.32

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM