如何获取具有给定类名的未知类的对象
我正在寻找一种方法来确定在运行时应该分配哪种类型的对象(基于给定的类名,其类型为 const char* )。
好吧,最简单的方法当然是使用大量 if
s /else if
s,但这似乎不适用,因为我有 > 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
失败
您有任何想法,如何解决此问题,或任何其他想法吗? 谢谢。
编辑:我解决了它:
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
变量或函数可以解决此问题,但会增加大量工作(当然您可以为此使用宏,但如果您已经使用宏,您也可以使用另一个对象工厂方法)
I am searching for a way to determine at runtime, which type of object should be alloced (based on a given class name, which is of type const char*
).
Well the simplest way of course is to use loads of if
s /else if
s, but that doesnt seem applicable, because i have > 100 different classes(well at least they all derive from one base class), and i have to add new classes quite regularly aswell.
I already came up with a first draft, but sadly it doesnt compile yet (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;
}
but that sizeof...(TArgs)>0
doesnt stop gcc from trying to generate code for get_classobject<TBase,const char*>(const char*)
which fails
Do you have any idea, how to fix this, or any other idea ?
Thanks.
EDIT: i solved it:
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);
}
EDIT For interested readers:
You should now that the implementation above is NOT compiler independent at all.
The output of typeif(sometype).name()
is compiler/implementation specific.
Using a static const char* name
variable or function inside all Derived classes, would fix this, but adds a bunch of work(of course you can use a macro for this, but if you are using macros already, you could aswell use another object factory method)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你就不能声明一下吗
?
然后你可以专门针对以下情况
Can't you just declare
?
Then you can specialize for the case of
阅读答案
Read the answers over here, you likely need a factory.
制作一个没有可变参数模板的专门的 get_classobject() 怎么样?这将停止递归。
然后,您将拥有一个带有可变参数模板的定义,以及另一个
template
的定义。另一个想法是创建一个仅接受 const char* 并返回 0 的非模板重载。How about making a specialized get_classobject() with no variadic temlates? That would stop the recursion.
You would then have one definition with variadic template, and another one of just
template<typename TBase, typename TDerived>
. Another idea is to make a non-template overload that accepts just const char*, and returns 0.这听起来像是您正在寻找经典的对象工厂模式。看看这个 stackoverflow 问题。我个人喜欢这个方法
This sounds like you are looking for the classical object factory pattern. Have a look at this stackoverflow question. Personally I like this method