How to get an object of a unknown class with given classname
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 wi开发者_Go百科th 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 oftypeif(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)Can't you just declare
template<typename TBase, typename TDerived, typename TArg, typename... TArgs>
?
Then you can specialize for the case of
typename TBase, typename TDerived, typename TArg
Read the answers over here, you likely need a factory.
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.
This sounds like you are looking for the classical object factory pattern. Have a look at this stackoverflow question. Personally I like this method
精彩评论