我正在寻找一种方法来确定在运行时应分配哪种类型的对象(基于给定的类名称,其类型为const char*
)。如何获得给定类名称的未知类的对象
嘛,当然最简单的方法是使用if
S/else if
小号加载,但似乎不适用,因为我有> 100个不同的类别(以及至少他们都来自同一个基类派生),我有定期增加新课程。
我已经想出了一个初稿,但遗憾的是它不编译,但(MinGW的& G ++ 4.4)
template<typename TBase, typename TDerived, typename... TArgs>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived; //
else if(sizeof...(TArgs)>0)
return get_classobject<TBase,TArgs...>(classname);
else
return 0;
}
int main()
{
Base* obj = get_classobject<Base,A,Foo,B,C>("Foo");
// ^- Types A B C and Foo are all derived from Base
delete obj; //of course we got an virtual dtor ;)
return 0;
}
但试图生成代码sizeof...(TArgs)>0
犯规停止GCC为get_classobject<TBase,const char*>(const char*)
从而未能
你有任何想法,如何解决这个问题,或任何其他想法? 谢谢。
编辑:我解决了这个问题:
template<typename TBase, typename TDerived>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived;
return 0;
}
template<typename TBase, typename TDerived, typename TArg, typename... TArgs>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived;
return get_classobject<TBase,TArg,TArgs...>(classname);
}
编辑感兴趣的读者:
您现在应该是执行上面没有编译器无关的。 typeif(sometype).name()
的输出是编译器/实现特定的。 在所有派生类中使用static const char* name
变量或函数,可以解决这个问题,但会添加一些工作(当然,您可以使用宏来实现此目的,但是如果您已经使用宏,则可以使用另一个对象工厂方法)
闻起来就像你需要实现一个工厂和'clone'方法。使用'clone()'接口,你可以创建一个家族的对象,而不需要知道他们的类名。 – 2010-01-16 01:04:17
我不想看起来很重要,但真的......这味道不好。首先,'typeid'的使用是颇有争议的,但我也想指出这种方法的低效性>你执行一个线性复杂的搜索,并且你必须精确地确定所有可能生成的类型。 ..我甚至不想考虑噩梦般的维护成本。 – 2010-01-16 16:47:30
typeid可以很容易地用static :: name函数代替,线性搜索不是一个问题,因为我只调用这个方法一次(除此之外,任何其他对象工厂ive看过也有一个线性搜索或滥用宏) – smerlin 2010-01-16 19:03:47