假设我有100个派生自Base的类。这些派生类中的每一个都具有[0,100]之间的唯一标识符,在编译时已知。
我有一个带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;
};
我是愚蠢的,还是有另一种方法,不需要这么多空间?
答案 0 :(得分:1)
对于每个都有一个巨大的开关盒显然不是一个好的解决方案 ID。
这实际上是抽象的工厂模式,它就像你描述的那样被广泛使用。我会坚持,因为它对大多数程序员来说都很熟悉。
您的变体似乎过于复杂且难以维护。
答案 1 :(得分:0)
在这种情况下,旧的硬件宏功能可以简化任务并消除一些错误。
#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