在运行时将ID解析为派生类型
Resolving an ID to a derived type at runtime
假设我有100个从Base派生的类。这些派生类中的每一个都有一个在[0100)之间的唯一标识符,在编译时已知
我有一个函数,它接受一个ID,并需要返回一个新分配的带有该ID的派生类实例。
Base* CreateDerived(uint32_t id) {
return new Derived...();
}
显然,为每个ID都设置一个巨大的交换机案例不是一个好的解决方案。下面提供了我能想到的最佳解决方案的示例,但我觉得有一种方法可以做到这一点,而不需要vtable带来的开销。
struct RegisteredClass {
static RegisteredClass* ClassTable[MAX_DERIVED_CLASSES];
static Base* CreateDerived(int ID) { return ClassTable[ID]->Create(); }
RegisteredClass(int ID) { ClassTable[ID] = this; }
virtual Base* Create() = 0;
};
template<typename T, int ID>
struct Register : RegisteredClass {
Register() : RegisteredClass(ID) { }
virtual Base* Create() { return new T; }
};
class Derived34 : Base {
static Register<Derived34, 34> _register;
};
我是在傻吗,还是有其他不需要那么多空间的方法?
显然,每个都有一个巨大的开关箱不是一个好的解决方案ID。
这实际上是抽象的工厂模式,正如你所描述的那样,它被广泛使用。我会坚持它,因为它对大多数程序员来说都很熟悉。
您的变体似乎过于复杂,难以维护。
在这种情况下,旧的crusty宏功能可以简化任务并消除一些错误。
#define CASE(n) case n: return new Derived##n
Base* CreateDerived(uint32_t id)
{
switch(id)
{
CASE(1);
CASE(2);
CASE(3);
// ...
default:
throw std::logic_error("Unhandled Derived## case");
}
}
#undef CASE
相关文章:
- 在 C++ 中用派生类型重写成员函数
- 在 C++ 中将对象转换为派生类型
- C++如果采用类类型的函数被传递派生类型,有没有办法给出错误?
- 返回派生类型时出现协变类型错误
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 基于派生类型的编译时行为分支
- 按类型排序向量并按类型或派生类型搜索
- 为什么"运算符<<"不适用于指向派生类型的成员?
- 无法返回派生类型的标准::unique_ptr<>
- 无法从派生类型的作用域访问另一个实例的受保护成员
- dynamic_cast到具有未知模板参数的派生类型
- 派生类型的成员
- 视觉C++ dynamic_cast返回 NULL,尽管对象是派生类型
- 在运算符中动态强制转换为派生类型<<
- 如何在不转换回基类类型的情况下返回派生类型的对象?
- 将派生指针分配给C 中的其他派生类型
- 如何将派生类型的对象放在用于基本类型的向量中
- C++ - 无法将派生类型作为基类型列表传递给构造函数
- 如何在基本类型参考中存储对派生类型的参考
- 统一处理具有协变类型的函数指针(如何使用派生类型调用回调?