复制构造函数以转移unique_ptr的所有权
Copy Constructor to transfer ownership of a unique_ptr
我需要编写一个复制构造函数,它还可以转移被复制对象的unique_ptr成员的所有权。情况如下:
class C{
// C class stuff
};
class A{
public:
public A();
public A(const A& a);
private:
std::unique_ptr<C> c_;
}
class B{
public:
B(const A& b) : a_(a){}
private:
A a_;
};
我应该如何实现A
的复制构造函数?
我想你的意图或方法是错误的。
复制构造函数旨在创建参数的副本,但由于unique_ptr
拥有唯一所有权,因此无法对其进行复制。实际上,可以使unique_ptr成员成为mutable
,然后在复制构造函数中移动它指向的资源,但这绝对是疯狂的(std::auto_ptr
就是这样做的,这也是它被弃用的原因)。
因此,您需要:
- 向a和B添加一个move构造函数(+使复制构造函数被删除)
- 从
unique_ptr
切换到shared_ptr
,但前提是C实际上是要共享的
还有第三种选择,即在a的复制构造函数中复制unique_ptr所指向的对象,即:
A::A(const A& a) : c_(std::unique_ptr<C>(a.c_ ? new C(*a.c_) : nullptr)) {
}
显然,由于std::unique_ptr
的赋值运算符已被删除,因此不能只对其进行赋值。这是为了迫使程序员定义他想要的行为。
- 新项目拥有
c_
的所有权,使原始项目无效 - 新项目制作
c_
的副本,保留原始项目的有效性 - 新项目共享
c_
的所有权,以便新项目和原始项目都引用同一对象
在情况1中,您要查找的是一个移动构造函数,默认的移动构造函数可以正常工作。所以你不需要写任何代码,你只需要做:
A temp;
A foo(std::move(temp));
请注意,temp
在移动后无效
在情况2中,您需要向A
添加一个自定义副本构造函数,以创建原始c_
:的副本
A(const A& a):c_(new C(*(a.c_))){}
在A
中定义后,您可以执行以下操作:
A foo(A());
请注意,这取决于C
的复制构造函数是否有效
在情况3中,您需要从根本上将A
从使用std::unique_ptr
更改为使用std::shared_ptr
,因此c_
的定义将变为:
std::shared_ptr<C> c_;
c_
的构造将与您已经用于std::unique_ptr
版本的c_
的构造相同。因此,只需使用默认实现即可:
A foo;
A bar(foo);
现在foo
和bar
指向同一个C
对象,并共享该对象的所有权。在删除所有引用该共享对象的shared_ptr
之前,该共享对象不会被删除。
从技术上讲,到
"编写一个复制构造函数,该构造函数还转移被复制对象的unique_ptr成员的所有权
你可以这样做:
class Bad
{
private:
unique_ptr<int> p_;
public:
Bad(): p_( new int(666) ) {}
Bad( Bad& other )
: p_( move( other.p_ ) )
{}
};
因为除了更传统的Bad( const Bad& )
之外,复制构造函数还可以有这个签名,再加上两个签名。
我把那个类命名为Bad
,因为它真的很糟糕,除了破坏别人的代码之外,做这件事是没有意义的。
不是一个不复制的复制构造函数
实现移动的移动构造函数,或
实现复制的普通复制构造函数,或
将类设计更改为例如共享所有权。
- 我是否需要在下一次转移时将所有权*转移回转移队列
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 智能指针概念所有权和寿命
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 对象超出范围/转让所有权
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 在不授予所有权的情况下公开shared_pointers载体
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 分离类所有权和使用,生成最佳(快速)代码
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 唯一 ptr 将所有权移动到包含对象的方法
- 从没有所有权的容器中清理智能 Ptr 的模式