7

I need a way to instantiate objects based on its class name passed by as a std::string. This is working right now, but need to be generalized:

void* create(std::string name) {
    if(name == "classOne") return new ClassOne();
    else if(name == "classTwo") return new ClassTwo();
    /* ... */
}

What i do not have:

  • Control over the classes to be instantiated: could be thirty party classes. No changes may be done to this classes (i.e. base ancestor, polymorphic creator method, etc...)
  • Full class name listing: more classes could be added later and should not incur in changes to this factory.
  • Wrappers around the classes to be instantiated: As a result of the previous two points.

Anything else is a go.

The best use case scenario will be:

int main() {
    void *obj = create("classTree"); // create object based on the string name
    /* ... */
    // once we know by context which specific class we are dealing with
    ClassTree *ct = (ClassTree*)obj; // cast to appropiate class
    std::cout << ct->getSomeText() << std::endl; // use object
}

As a side, and maybe irrelevant note, take in account the object to be instantiated may come from a class or a struct.

ADDED INFORMATION

I see more context is needed. Here is my particular use case, simplified:

// registration mechanism
int main() {
    std::map< std::string, void(*func)(std::string, void*) > processors; // map of processors by class name
    processors["ClassFour"] = (void(*)(std::string, void*)) &classFourMessageProcessor; // register processor (cast needed from specific to generic)
}
// function receiving string messages
void externalMessageHandler(std::string msg) {
    std::string objType = extractTypeFromMessageHeader(msg); // extract type from message
    // now that we know what we are dealing with, create the specific object
    void *obj = create(objType); // << creator needed
    processors[objType](msg, obj); // dispatch message to process
}
// previously registered message processor
void classFourMessageProcessor(std::String msg, ClassFour *obj) {
    std::string streetAddress = msg.substr(10, 15); // knowing the kind of message we can extract information
    obj->moveTheEtherTo(streetAddress); // use the created object
}

ADDED INFORMATION

I am using C++11 with the latest GNU compiler.

4

4 に答える 4

-1

Boost.MPL を検討しますか? STL とは異なり、インスタンスではなく型を含むコンテナーを作成できます。文字列から型へのマップがあれば、目的のファクトリが得られますね。

于 2013-09-26T20:30:08.710 に答える