user1054922 user1054922 - 1 year ago 86
C++ Question

Use String-To-Class Lookup table in C++ to instantiate classes

Looking for a way to avoid a massive IF/ELSE and use a lookup table to resolve strings to particular classes to instantiate, that all derive from a base class.
Is something like this possible, and if so, how?

typedef struct BaseClass
} BaseClass;

typedef struct DerivedClassOne : BaseClass
} DerivedClassOne;

typedef struct DerivedClassTwo : BaseClass
} DerivedClassTwo;

typedef struct
const char *name;
BaseClass class;
} LookupList;

LookupList list[] = {
{"ClassOne", DerivedClassOne},
{"ClassTwo", DerivedClassTwo}

BaseClass *InstantiateFromString(char *name)
int i;
for (i = 0; i < 2; i++)
if (!strcmp(name, list[i].name))
return new list[i].class();

int main (int argc, char *argv[])
BaseClass *myObjectFromLookup = InstantiateFromString("ClassOne");

Answer Source

If your compiler is compatible with C++11, you can easily do that with lambdas and std::map:

#include <iostream>
#include <string>
#include <map>
#include <functional>

using namespace std;

struct BaseClass {virtual void foo()=0;};
struct DerivedClass1 : public BaseClass {void foo() {cout << "1" << endl;}};
struct DerivedClass2 : public BaseClass {void foo() {cout << "2" << endl;}};

// Here is the core of the solution: this map of lambdas does all the "magic"
map<string,function<BaseClass*()> > factory {
    {"one", [](){return new DerivedClass1();}}
,   {"two", [](){return new DerivedClass2();}}

int main() {
    BaseClass *a = factory["one"](); // Note the function call () at the end
    BaseClass *b = factory["two"]();
    delete a;
    delete b;
    return 0;

The idea is to make a map that gives you a function that makes an appropriate subclass.

Demo on ideone.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download