类 的复制构造函数实例化派生 类

Copy Constructors of classes instantiating derived classes

我一直在尝试创建 class 的复制构造函数以实例化派生的 class。

假设我有以下纯虚拟 class:

class AbstractBar{
public:
    virtual void printMe() = 0;

};

Class Bar 继承自 AbstractBar 如下:

class Bar: public AbstractBar {
    std::string name_;

public:
    explicit Bar(std::string name) : name_ {std::move(name)}{};

    void printMe() override { std::cout << name_ << std::endl; }
};

我的 class Foo 现在尝试通过声明一个指向类型 AbstractClass 的指针来利用多态性,如下所示:

class Foo{
    std::unique_ptr<AbstractBar> theBar_;

public:
    explicit Foo(std::unique_ptr<Bar> bar){
        theBar_ = std::move(bar);
    };

    void printBar(){
        theBar_->printMe();
    }
};

但是我确实希望 Foo 被复制,所以我添加了以下复制构造函数:

    Foo(const Foo &other) {
        theBar_ = std::unique_ptr<AbstractBar>();
        *theBar_ = *(other.theBar_);
    }

这就是问题所在。

我收集到的是,这可能是一个问题,因为复制构造函数中的 theBar 认为它指向一个 AbstractBar 但是当我尝试复制它指向的对象时,在下一行,我实际上给它派生了 Bar class.

有没有合适的方法来实现这个拷贝构造函数?

首先,std::unique_ptr<T>确实是独一无二的。因此,您不能指望通过复制两件事来指向相同的 instance-of-whatever。也就是说,我 认为 你想要做的是 克隆 无论该成员持有什么“东西” unique_ptr 允许 deep 副本 Foo.

如果是这样,您需要协变 克隆。见下文:

#include <iostream>
#include <string>
#include <memory>

struct AbstractBar
{
    virtual ~AbstractBar() = default;

    virtual std::unique_ptr<AbstractBar> clone() = 0;
    virtual void printMe() = 0;
};

class Bar : public AbstractBar
{
    std::string name_;

public:
    explicit Bar(std::string name) : name_{std::move(name)} {};

    std::unique_ptr<AbstractBar> clone() override
    {
        return std::make_unique<Bar>(name_);
    }

    void printMe() override
    {
        std::cout << name_ << std::endl;
    }
};

class Foo
{
    std::unique_ptr<AbstractBar> theBar_;

public:
    explicit Foo(std::unique_ptr<Bar> bar)
        : theBar_(std::move(bar))
    {
    }

    Foo(const Foo &other)
        : theBar_(other.theBar_->clone())
    {
    }

    void printBar()
    {
        theBar_->printMe();
    }
};

int main()
{
    Foo foo(std::make_unique<Bar>("Some String"));
    Foo bar(foo);

    foo.printBar();
    bar.printBar();
}

重要提示:foobar 将通过指向 Bar 的抽象基础的唯一指针分别拥有自己的 Bar 实例,即 AbstractBar .希望这是意图。这不是唯一的方法,但它可能是最容易理解的。