在C++中使用String-To-Class Lookup表来实例化类

use*_*922 6 c++

寻找一种避免大规模IF/ELSE并使用查找表将字符串解析为特定类来实例化的方法,这些方法都来自基类.这是可能的,如果是这样,怎么样?

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");
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 5

如果您的编译器与C++ 11兼容,您可以使用lambdas轻松地执行此操作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"]();
    a->foo();
    b->foo();
    delete a;
    delete b;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是创建一个映射,为您提供一个函数,使其成为一个合适的子类.

在ideone上演示.