[英]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.