如何在C++中存储初始化器列表,实现多子类的枚举选择初始化?
用枚举映射初始化子类,替代switch语句
核心思路
核心是建立枚举值到子类初始化逻辑的映射关系,用关联容器(比如C++的unordered_map、Python的字典)存储这种对应关系,这样新增或修改子类时,只需要更新映射表,完全不用动初始化函数的核心逻辑。
C++ 实现示例
先定义基类、子类和枚举:
#include <iostream> #include <unordered_map> #include <memory> #include <stdexcept> // 基类 class Base { public: virtual void doSomething() = 0; virtual ~Base() = default; }; // 子类A class DerivedA : public Base { public: void doSomething() override { std::cout << "DerivedA 执行操作\n"; } }; // 子类B class DerivedB : public Base { public: void doSomething() override { std::cout << "DerivedB 执行操作\n"; } }; // 枚举:每个值对应一个子类 enum class DerivedType { TypeA, TypeB };
接着创建映射表和统一初始化函数:
// 定义工厂函数类型:返回基类的智能指针 using FactoryFunc = std::unique_ptr<Base>(*)(); // 初始化映射表:枚举值对应子类的构造逻辑 std::unordered_map<DerivedType, FactoryFunc> factoryMap = { {DerivedType::TypeA, []() { return std::make_unique<DerivedA>(); }}, {DerivedType::TypeB, []() { return std::make_unique<DerivedB>(); }} }; // 统一初始化入口 std::unique_ptr<Base> createDerived(DerivedType type) { auto it = factoryMap.find(type); if (it != factoryMap.end()) { return it->second(); } throw std::invalid_argument("无效的子类枚举值"); }
使用方式:
int main() { auto objA = createDerived(DerivedType::TypeA); objA->doSomething(); // 输出:DerivedA 执行操作 auto objB = createDerived(DerivedType::TypeB); objB->doSomething(); // 输出:DerivedB 执行操作 return 0; }
Python 实现示例
Python的实现更简洁,直接利用字典映射子类构造函数:
from abc import ABC, abstractmethod from enum import Enum # 基类 class Base(ABC): @abstractmethod def do_something(self): pass # 子类A class DerivedA(Base): def do_something(self): print("DerivedA 执行操作") # 子类B class DerivedB(Base): def do_something(self): print("DerivedB 执行操作") # 枚举类型 class DerivedType(Enum): TYPE_A = 1 TYPE_B = 2 # 映射表:枚举直接对应子类 factory_map = { DerivedType.TYPE_A: DerivedA, DerivedType.TYPE_B: DerivedB } # 统一初始化函数 def create_derived(type_enum): cls = factory_map.get(type_enum) if cls: return cls() raise ValueError("无效的子类枚举值")
使用方式:
if __name__ == "__main__": obj_a = create_derived(DerivedType.TYPE_A) obj_a.do_something() # 输出:DerivedA 执行操作 obj_b = create_derived(DerivedType.TYPE_B) obj_b.do_something() # 输出:DerivedB 执行操作
注意事项
- 如果子类需要构造参数,只需调整映射表中的工厂函数,让它接收参数并传递给子类构造即可
- 新增子类时,只需要在枚举中添加对应值,再把子类加入映射表,完全不用修改初始化函数,符合开闭原则
- 必须处理无效枚举值的情况,避免空指针或错误实例
内容的提问来源于stack exchange,提问作者Arjun
相关产品推荐
相关产品推荐

