Copy constructor for a class that has unique ptr of a Base class [duplicate]

若如初见. 提交于 2020-01-15 08:30:13

问题


When a class has a unique_ptr of a Base class what is a good way to implement the copy constructor.

Let me try to explain it with an example:

struct Base
{
    virtual void doSth() = 0; // to make the class abstract.
};

struct Derived : public Base
{
    virtual void doSth() override {}
};

struct Foo
{
    std::unique_ptr<Base> bar;

    Foo(const Foo& other) : bar(new Base(*other.bar))   // cant do it, its abstract.
    {
        bar = std::move(other.bar); // cant do it, reference object is modified.
    }
};

Here as the class is abstract i cannot use its copy constructor. and also cannot use move on a constant reference ( we shouldnt do it actually, do not modify the object).

What I end up with is like so:

struct Base
{
    virtual void doSth() = 0; // to make the class abstract.
};

struct Derived : public Base
{
    virtual void doSth() override {}

    Derived(const Base* b)
    {

    }
};

struct Foo
{
    std::unique_ptr<Base> bar;

    Foo(const Foo& other) : bar(new Derived(other.bar.get()))
    {

    }
};

However, it does not feel quite right, does it?


回答1:


If you need to copy polymorphically, you will need to provide that in the interface of the type you are holding. Add a clone virtual function to Base and use that to create a copy that you can store in the copied Foo.

Other alternatives include not copying (delete the copy constructor) or use reference semantics (copies refer to the same object: change unique_ptr for shared_ptr) but neither of those alternatives really provide copies.




回答2:


Here is the code for David's answer. Note that the virtual clone() is described in this answer.

#include <stdlib.h>
#include <cstddef>
#include <memory>


struct Base
{
   virtual void doSth() = 0; // to make the class abstract.
   virtual Base* clone() const = 0;
};

struct Derived : public Base
{
    virtual void doSth() override {}
    virtual Derived* clone() const {
        return new Derived(*this);
    }
};

struct Foo
{
    std::unique_ptr<Base> bar;

    Foo(const Foo& other) : bar(other.bar->clone())   // cant do it, its abstract.
    {

    }
};


来源:https://stackoverflow.com/questions/23717967/copy-constructor-for-a-class-that-has-unique-ptr-of-a-base-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!