You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于基类引用创建指向其副本的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:22:43