如何重新分配(也称为集合)unique_ptr类成员?

How can you re-assign (a.k.a set) class member that is unique_ptr?

本文关键字:unique ptr 成员 集合 分配 何重新      更新时间:2023-10-16
class A {};
class B{
unique_ptr<A> upA;
public:
B() : upA(make_unique<A>()) {}
void set(A a){
upA.reset(move(a));  //error
//upA.reset(a);        //error
//upA = move(a);     //error
}
};

如何重新分配(也称为集合)unique_ptr类成员?

这取决于你想做什么。是否要在upA管理的对象上调用operator=?㞖:

*upA = a;

您想接受新unique_ptr并拥有它吗?㞖:

void set(std::unique_ptr<A> a){
upA = move(a);
}
unique_ptr<A> upA;

所以这是一个独特的(智能)指针,指向位于某处的 A - 到目前为止还不错。

B() : upA(make_unique<A>()) {}

好的,我们初始化指针以指向一个新的、动态分配的A- 看起来很合理。

void set(A a){
upA.reset(move(a));

但是现在您想将智能指针(负责管理它指向的对象的生存期)指向 A 的本地实例?这没有意义,原因有两个:

  1. 智能指针管理指针,并且您正在向其传递一个本地对象(左值引用)。您可以通过编写&a将其转换为指针,但这仍然存在以下问题:
  2. 当函数返回时,您的局部变量a将超出范围,使您的智能指针具有悬而未决的无效地址,需要尝试管理。

当你打电话给B::set,应该发生什么?您需要从调用方的角度决定它打算做什么。也:

// transfer control of the caller's A to B
void B::set(std::unique_ptr<A> a) { upA = move(a); }

// take control of the caller's allocated but unmanaged A
void B::set(A *a) { upA.reset(a); }
// not recommended - keep everything managed by unique_ptr if at all possible

// copy the caller's A into B's existing A
void B::set(A const &a) { *upA = a; }
// called as
b.set(my_local_a);

// move the caller's temporary A into B's existing A
void B::set(A &&a) { *upA = move(a); }
// called with an explicit move
b.set(move(my_local_a));
// or with a prvalue
b.set(A{});