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
相关产品推荐
相关产品推荐

