Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ifs /else ifs, 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)

like image 936
smerlin Avatar asked Dec 04 '25 10:12

smerlin


1 Answers

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
like image 129
Kornel Kisielewicz Avatar answered Dec 07 '25 01:12

Kornel Kisielewicz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!