[英]Reassign a smart pointer in a function without passing ownership?
With normal pointers, I can do something like the following 使用普通的指针,我可以执行以下操作
void conditional_reassign(MyClass* ptr)
{
if (my_condition)
{
delete ptr;
ptr = new MyClass(new_param);
}
}
And I can pass in the pointer I want to change like following 我可以像下面那样传递我想要更改的指针
MyClass* ptr = new MyClass(old_param);
conditional_reassign(ptr);
I wish to reimplement this with std::unique_ptr
. 我想用
std::unique_ptr
重新实现。 Here's what I came up with 这是我想出的
std::unique_ptr<MyClass> conditional_reassign2(std::unique_ptr<MyClass> ptr)
{
if (my_condition)
{
ptr = std::make_unique<MyClass>(new_param);
}
return std::move(ptr);
}
And I would call it with the following 我会用以下内容来称呼它
std::unique_ptr<MyClass> ptr = make_unique<MyClass>(old_param);
ptr = std::move(conditional_reassign2(std::move(ptr)));
I'm not quite happy with the verbosity of the line 我对这行的详细程度不太满意
ptr = conditional_reassign2(std::move(ptr));
Is there a way to implement conditional_reassign2
so that I can call it in a manner similar to conditional_reassign(ptr)
有没有一种方法可以实现
conditional_reassign2
所以我可以用类似于conditional_reassign(ptr)
的方式来调用它
I should note a major issue with 我应该注意一个主要问题
ptr = std::move(conditional_reassign2(std::move(ptr)));
is that it will destroy the original object ptr
pointed to regardless of my_condition
(see Why does reassigning a smart pointer to itself cause destruction? ) 不管
my_condition
是否都会破坏指向的原始对象ptr
(请参阅为什么将智能指针重新分配给自身会导致破坏? )
Either you need to pass the pointer by reference 您要么需要通过引用传递指针
void conditional_reassign2(std::unique_ptr<MyClass>& ptr) {...}
std::unique_ptr<MyClass> myPtr;
conditional_reassign2(myPtr);
or return the pointer, which requires a single move 或返回指针,只需移动一下
std::unique_ptr<MyClass> conditional_reassign2(std::unique_ptr<MyClass> ptr) {...}
std::unique_ptr<MyClass> myPtr;
myPtr = conditional_reassign2(std::move(myPtr));
Also you can return ptr directly from the function without explicitly calling move. 另外,您可以直接从函数返回ptr,而无需显式调用move。
std::unique_ptr<MyClass> conditional_reassign2(std::unique_ptr<MyClass> ptr)
{
if (my_condition)
ptr = std::make_unique<MyClass>(new_param);
return ptr;
}
You can define the conditional_reassign2()
function to take the std::unique_ptr
by reference instead of by value : 您可以定义
conditional_reassign2()
函数以通过引用而不是通过值获取std::unique_ptr
:
void conditional_reassign2(std::unique_ptr<MyClass>& ptr)
{
if (my_condition)
{
ptr = std::make_unique<MyClass>(new_param);
}
}
This way the function can directly modify the instance that is being passed, no need to transfer the ownership. 这样,函数可以直接修改正在传递的实例,而无需转移所有权。
Assuming that ptr
is an std::unique_ptr<MyClass>
, then calling conditional_reassign2()
would be in this case: 假设
ptr
是std::unique_ptr<MyClass>
,则在这种情况下调用conditional_reassign2()
将是:
conditional_reassign2(ptr);
Your first example does not do what you intend it to do. 您的第一个示例未达到您的预期目的。 As
ptr
is passed by value, the caller's pointer will not be modified. 当通过值传递
ptr
,将不会修改调用方的指针。 So if my_condition
is true
, the caller has a pointer that points to a deleted object, and the address to which the newly created object is stored at is lost after the function returns. 因此,如果
my_condition
为true
,则调用方将拥有一个指向已删除对象的指针,并且该函数返回后,新创建的对象所存储的地址将丢失。
Here is your first example fixed (the argument is now a reference to a pointer): 这是您的第一个固定示例(参数现在是对指针的引用):
void conditional_reassign((MyClass*)& ptr)
{
if (my_condition)
{
delete ptr;
ptr = new MyClass(new_param);
}
}
To use unique_ptr, you can also use references and not return anything. 要使用unique_ptr,您还可以使用引用而不返回任何内容。 This way no need to deal with
std::move
这样就无需处理
std::move
void conditional_reassign2(std::unique_ptr<MyClass>& ptr)
{
if (my_condition)
{
ptr = std::make_unique<MyClass>(new_param);
}
}
You can call it like this: 您可以这样称呼它:
std::unique_ptr<MyClass> ptr = make_unique<MyClass>(old_param);
conditional_reassign2(ptr);
Or you can use return/move semantics: 或者,您可以使用return / move语义:
std::unique_ptr<MyClass> conditional_reassign(std::unique_ptr<MyClass> ptr)
{
if (my_condition)
{
return std::make_unique<MyClass>(new_param);
}
return ptr;
}
And call it like this: 并这样称呼它:
std::unique_ptr<MyClass> ptr = make_unique<MyClass>(old_param);
ptr = conditional_reassign2(std::move(ptr));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.