繁体   English   中英

复制构造函数以转移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 ,然后将它指向的资源移动到copy-constructor中,但这绝对是疯狂的(这就是std::auto_ptr作用,这就是为什么它已被弃用)。

因此,您需要:

  • 向A和B添加一个move-constructor(+ make copy-constructor deleted)
  • 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因为它们的赋值运算符被删除了。 这是故意迫使程序员定义他想要的行为。

  1. 新项目取得c_所有权,使原始项目无效。
  2. 新项目复制了c_ ,保留了原始项目的有效性。
  3. 新项目共享c_所有权,以便新项目和原始项目引用同一对象。

案例1中 ,您要查找的是移动构造函数,默认移动构造函数将正常工作。 所以你不需要编写任何代码,你可以这样做:

A temp;
A foo(std::move(temp));

请注意,移动后temp无效。

第二种情况下 ,您需要一个自定义的拷贝构造函数添加到A创建原始的副本c_

A(const A& a):c_(new C(*(a.c_))){}

A定义后,您可以:

A foo(A());

请注意,这取决于C的复制构造函数是否正常。

在第3种情况下,您需要从使用std::unique_ptr到使用std::shared_ptr从根本上改变A ,因此c_的定义将变为:

std::shared_ptr<C> c_;

您对c_构造将与您已经用于c_std::unique_ptr版本的构造相同。 所以只需使用您可以执行的默认实现:

A foo;
A bar(foo);

现在foobar指向同一个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因为它非常糟糕,除了破坏别人的代码之外,做这件事是没有意义的。

而不是不复制的复制构造函数,

  • 实现此举的构造函数, 移动 ,或

  • 实现一个普通的拷贝构造函数, 拷贝 ,或

  • 将班级设计改为例如共享所有权

暂无
暂无

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

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