当一个类具有Base类的unique_ptr时,实现复制构造函数的好方法是什么。
让我试着用一个例子来解释它:
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.
}
};
这里的类是抽象的,我不能使用它的复制构造函数。并且也不能在常量引用上使用move(我们实际上不应该这样做,不要修改对象)。
我最终得到的是:
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()))
{
}
};
然而,它感觉不太对,是吗?
答案 0 :(得分:2)
如果需要以多态方式进行复制,则需要在所持类型的界面中提供。将clone
虚拟函数添加到Base
并使用该函数创建副本,您可以将其存储在复制的Foo
中。
其他替代方法包括不复制(删除复制构造函数)或使用引用语义(复制引用相同的对象:unique_ptr
更改shared_ptr
)但这两种选择都不提供副本
答案 1 :(得分:2)
以下是David回答的代码。请注意,this answer中描述了虚拟clone()
。
#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.
{
}
};