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

C++成员vector存储基类指针时如何维持多态避免对象切片

实现方案

要实现多态场景下的对象深拷贝、避免对象切片,标准解决方案是给基类添加虚克隆(clone)方法,由每个派生类自行实现自身的拷贝逻辑,运行时会自动匹配指针指向的实际类型执行拷贝。

修改后的完整代码示例

#include <vector>

class Base{
public:
    // 基类实现虚克隆函数,返回自身拷贝的指针
    virtual Base* clone() const {
        return new Base(*this);
    }
    // 必须添加虚析构函数,否则后续释放对象时会触发未定义行为
    virtual ~Base() = default;
};

class Derived: public Base{
public:
    // 派生类重写克隆函数,C++支持协变返回类型,可直接返回派生类指针
    Derived* clone() const override {
        return new Derived(*this);
    }
};

class Foo{
private:
    std::vector<Base*> vec;
public:
    Foo() = default;
    void addObject(const Base* b){
        // 调用虚克隆函数,自动匹配实际类型的拷贝逻辑
        vec.push_back(b->clone());
    }
    // 补充析构函数释放vector中存储的对象,避免内存泄漏
    ~Foo() {
        for (auto obj_ptr : vec) {
            delete obj_ptr;
        }
    }
    // 建议删除默认拷贝/移动逻辑,避免重复释放内存
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
    Foo(Foo&&) = delete;
    Foo& operator=(Foo&&) = delete;
};

int main(){
    Derived* d = new Derived();
    Base* b = new Base();
    Foo f;
    f.addObject(d);
    f.addObject(b);
    
    delete d;
    delete b;
    return 0;
}

补充说明

  • 如果使用C++11及以上版本,更推荐用std::unique_ptr<Base>/std::shared_ptr<Base>等智能指针代替裸指针管理资源,不需要手动写析构释放逻辑,安全性更高。智能指针场景下克隆函数返回值改为对应智能指针即可,仅需注意协变特性仅支持裸指针和引用,派生类重写时返回值和基类保持一致的智能指针类型即可。
  • 如果基类不需要被实例化,也可以把clone函数定义为纯虚函数,强制所有派生类都实现拷贝逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:24:04