如何将std::unique_ptr与多态机制结合使用?从子类初始化方法
如何将std::unique_ptr与多态特性结合使用
你的代码抛出异常的核心原因有两个:
Abstract是抽象类,无法直接实例化,std::make_unique<Abstract>试图创建抽象类对象,必然失败。- 即使
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
相关产品推荐
相关产品推荐

