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:
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.
You can just store a factory function for every class type. An easy way is to use a template
template <typename T>
void* creator() {
return new T();
}
and store those in the map as well (i.e. "ClassFour" links to creator<ClassFour>
and to ClassFourMessageProcessor
).
Edit: for clarification, processors
becomes a
typedef void* (*CreatorFunc)();
typedef void (*ProcessorFunc)(std::string, void*);
typedef std::pair<CreatorFunc, ProcessorFunc> Entry;
std::map< std::string, Entry > processors;
Adding a new class is as simple as
processors["SomeClass"] = Entry(creator<SomeClass>, ClassFourMessageProcessor);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With