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

如何将std::unique_ptr与多态机制结合使用?从子类初始化方法

如何将std::unique_ptr与多态特性结合使用

你的代码抛出异常的核心原因有两个:

  1. Abstract是抽象类,无法直接实例化,std::make_unique<Abstract>试图创建抽象类对象,必然失败。
  2. 即使Abstract不是抽象类,直接通过基类引用拷贝会触发对象切片,只能复制基类部分的内容,无法保留子类的特有数据和行为。

要实现从任意子类对象初始化std::unique_ptr<Abstract>,需要借助多态克隆的方式,具体步骤如下:

步骤1:给基类添加虚析构函数和纯虚克隆方法

基类必须有虚析构函数,否则unique_ptr销毁对象时无法正确调用子类的析构函数,会导致内存泄漏。同时添加纯虚的clone方法,让子类实现自己的拷贝逻辑。

步骤2:子类实现克隆方法

每个子类重写clone方法,返回自身对象的unique_ptr<Abstract>(利用unique_ptr的向上转型特性)。

修改后的完整代码

#include <memory>

class Abstract {
public:
    // 必须添加虚析构函数
    virtual ~Abstract() = default;
    virtual void foo() = 0;
    // 纯虚克隆方法,返回子类对象的unique_ptr
    virtual std::unique_ptr<Abstract> clone() const = 0;
};

class Child1 final : public Abstract {
public:
    void foo() override {}
    std::unique_ptr<Abstract> clone() const override {
        return std::make_unique<Child1>(*this);
    }
};

class Child2 final : public Abstract {
public:
    void foo() override {}
    std::unique_ptr<Abstract> clone() const override {
        return std::make_unique<Child2>(*this);
    }
};

void bar(const Abstract& a) {
    // 调用多态的clone方法,获取子类对象的副本
    std::unique_ptr<Abstract> ptr = a.clone();
    // 可以正常调用多态方法
    ptr->foo();
}

int main() {
    Child1 c1;
    Child2 c2;

    bar(c1);
    bar(c2);
}

补充说明

  • 克隆方法的返回值是std::unique_ptr<Abstract>,因为unique_ptr支持从派生类指针隐式转换为基类指针,符合多态需求。
  • 如果需要支持移动语义,还可以添加clone_move之类的方法,但大部分场景下拷贝克隆已经足够。
  • 确保子类的拷贝构造函数可用(默认生成的拷贝构造函数在没有自定义析构/拷贝/移动函数时是有效的,如上述代码中的Child1和Child2)。

内容的提问来源于stack exchange,提问作者a_nR1085__i

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:17:30