我有一个名为Base
和Derived
的类,我需要通过虚成员函数foo()
实现多态行为:
#include <iostream>
#include <memory>
class Base {
public:
virtual int foo() const = 0;
};
class Derived : public Base {
public:
int foo() const override { return 42; }
};
std::unique_ptr<Base> clone(Base & base) {
//auto copy = base; // cannot create an abstract type
//return std::make_unique(copy);
return std::make_unique(base);
}
int main() {
auto d = Derived();
auto p = clone(d);
std::cout << p->foo() << '\n';
}
无法编译:https://godbolt.org/z/voaGdf1sM
<source>: In function 'std::unique_ptr<Base> clone(Base&)':
<source>:19:28: error: no matching function for call to 'make_unique(Base&)'
19 | return std::make_unique(base);
| ~~~~~~~~~~~~~~~~^~~~~~
除了clone()
之外,我希望在程序的大部分地方都能够将Derived
实例视为值语义,但是有一种情况需要将Derived
实例添加到集合(std::vector<std::unique_ptr<Base>>
)并保留多态性,因此在这种情况下,我需要能够向新的副本的Derived
对象添加unique_ptr
s。因此,我有一个函数clone()
,它接受对Derived
对象的引用,并旨在创建一个副本,然后由unique_ptr
拥有,并返回该副本。
不幸的是,我无法弄清楚如何制作一个抽象类型如Base
的多态副本。
我不能通过值传递参数,然后将隐式副本移动到unique_ptr
中,因为无法拥有Base
的实例,而我需要多态性。
我研究了使用转发引用的方法,例如:
std::unique_ptr<Base> clone(Base && base) {
return std::make_unique(base);
}
// ...
auto p = clone(std::move(d));
但我不想在调用者处公开所有权并要求他们调用std::move
- 应该自由地传递对现有对象的引用,并期望clone
将其复制,而不是拥有它。我实际上希望它被复制,并且源对象保持完整并能够再次使用(例如制作更多副本)。
注意:如果我能让这个工作起来,那么clone
最好采用const Base &
,因为毕竟我是出于性能原因而通过引用传递。
我在尝试做的事情 - 复制一个被管理为unique_ptr
的副本,而不会对调用者施加移动语义 - 是否可能?
std::vector<unique_ptr<Base>>
并返回它,但我将其剥离以使其更简单,并无意中留下了名为“create”的函数。编辑:我已经在我的问题中将“create”重命名为“clone”。 - davidAclone()
是一个(虚)成员函数:如何通过基类指针克隆派生的C++类? -- 在C++中是否有可能克隆多态对象而不手动将重写的克隆方法添加到每个派生类中? -- 从基类指针克隆派生类 - JaMiTclone()
是一个(虚拟)成员函数:如何通过基类指针使派生的 C++ 类克隆自身? -- 在 C++ 中是否有可能在每个派生类中手动添加重写的克隆方法之前,克隆一个多态对象? -- 从基类指针克隆派生类 - undefined