如何基于基类引用创建指向其副本的unique_ptr?
多态对象的克隆实现方案
问题背景
现有包含纯虚函数的Base抽象类和Derived派生类,需要实现一个克隆函数:接收基类引用(最好是const引用),复制原对象并返回由std::unique_ptr<Base>管理的副本,同时不强制调用者使用移动语义,原对象保持可用。原代码因无法直接实例化抽象类而编译失败。
原代码:
#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; // 无法创建抽象类型 //return std::make_unique(copy); return std::make_unique(base); } int main() { auto d = Derived(); auto p = clone(d); std::cout << p->foo() << '\n'; }
编译错误:
<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); | ~~~~~~~~~~~~~~~~^~~~~~
解决方案
通过给基类添加虚克隆函数的方式实现,利用多态特性调用派生类的实际复制逻辑:
修改后的完整代码
#include <iostream> #include <memory> class Base { public: virtual int foo() const = 0; // 添加纯虚克隆函数,支持const对象 virtual std::unique_ptr<Base> clone() const = 0; }; class Derived : public Base { public: int foo() const override { return 42; } // 重写克隆函数,创建自身的副本 std::unique_ptr<Base> clone() const override { return std::make_unique<Derived>(*this); } }; // 全局克隆函数,接收const引用,调用对象自身的克隆逻辑 std::unique_ptr<Base> clone(const Base& base) { return base.clone(); } int main() { auto d = Derived(); auto p = clone(d); // 原对象d保持可用,复制出一个新的Derived实例 std::cout << p->foo() << '\n'; // 输出42,多态行为正常 }
关键说明
- 虚克隆函数:在Base类中声明纯虚的
clone()成员函数,派生类必须重写它。调用时会根据实际对象类型(比如Derived)执行对应的重写版本,创建正确类型的副本,避免抽象类实例化问题。 - const兼容:将成员函数和全局克隆函数都声明为
const,支持接收const修饰的基类引用,符合需求。 - 值语义保留:调用者无需使用
std::move,原对象不会被转移所有权,始终保持可用,同时完成复制操作。 - 多态性保持:返回的
unique_ptr<Base>指向实际的Derived对象,调用foo()时依然能触发多态行为。
内容的提问来源于stack exchange,提问作者davidA
相关产品推荐
相关产品推荐

