C++中如何创建可迭代列表存储含相同函数的不同类对象?
解决方案
首先修正你原有的createClass函数——模板参数T是类型,不需要传入对象实例,正确写法如下:
template<class T> std::shared_ptr<T> createClass() { return std::make_shared<T>(); }
针对你需要动态存储不同类对象并统一调用doStuff()的需求,提供两种常用实现方案:
方案一:基于多态的虚函数方案(侵入式,需修改原有类)
这是C++中处理此类问题的经典方案,利用多态特性实现统一调用:
- 定义一个包含纯虚
doStuff()的抽象基类 - 让所有类继承该基类并实现
doStuff() - 用基类智能指针的容器存储所有对象,遍历调用即可
#include <memory> #include <vector> // 抽象基类,定义统一接口 class Base { public: virtual void doStuff() = 0; // 纯虚函数,强制子类实现 virtual ~Base() = default; // 虚析构函数,确保子类对象正确销毁 }; // 修改原有类,继承Base并实现doStuff class A : public Base { public: void doStuff() override { // 此处实现A的doStuff逻辑 } }; class B : public Base { public: void doStuff() override { // 此处实现B的doStuff逻辑 } }; class C : public Base { public: void doStuff() override { // 此处实现C的doStuff逻辑 } }; // 调整createClass返回基类指针,方便统一存储 template<class T> std::shared_ptr<Base> createClass() { return std::make_shared<T>(); } // 遍历调用所有对象的doStuff void callAllDoStuff(const std::vector<std::shared_ptr<Base>>& objects) { for (const auto& obj : objects) { obj->doStuff(); } } // 使用示例 int main() { std::vector<std::shared_ptr<Base>> objects; objects.push_back(createClass<A>()); objects.push_back(createClass<B>()); objects.push_back(createClass<C>()); callAllDoStuff(objects); return 0; }
方案二:基于std::variant的非侵入式方案(无需修改原有类)
如果无法修改A、B、C的代码结构,可以用std::variant封装不同类型的智能指针,通过std::visit实现统一调用:
#include <memory> #include <vector> #include <variant> // 原有类无需修改 class A { public: void doStuff() { // A的doStuff实现 } }; class B { public: void doStuff() { // B的doStuff实现 } }; class C { public: void doStuff() { // C的doStuff实现 } }; // 修正后的createClass template<class T> std::shared_ptr<T> createClass() { return std::make_shared<T>(); } // 定义variant类型,包含所有可能的对象指针类型 using ObjectVariant = std::variant<std::shared_ptr<A>, std::shared_ptr<B>, std::shared_ptr<C>>; // 调用单个variant对象的doStuff void callDoStuff(const ObjectVariant& var) { std::visit([](const auto& obj) { obj->doStuff(); }, var); } // 遍历调用所有对象 void callAllDoStuff(const std::vector<ObjectVariant>& objects) { for (const auto& var : objects) { callDoStuff(var); } } // 使用示例 int main() { std::vector<ObjectVariant> objects; objects.push_back(createClass<A>()); objects.push_back(createClass<B>()); objects.push_back(createClass<C>()); callAllDoStuff(objects); return 0; }
注意事项
- 多态方案更适合需要动态扩展类型的场景,新增类只需继承基类即可;
- variant方案无需修改原有类,但新增类型时需要同步更新
ObjectVariant的类型列表; - 两种方案都依赖智能指针管理内存,避免手动释放导致的泄漏问题。
内容的提问来源于stack exchange,提问作者user22502145
相关产品推荐
相关产品推荐

