I have a file: Base.h
class Base;
class DerivedA : public Base;
class DerivedB : public Base;
/*etc...*/
and another file: BaseFactory.h
#include "Base.h"
class BaseFactory
{
public:
BaseFactory(const string &sClassName){msClassName = sClassName;};
Base * Create()
{
if(msClassName == "DerivedA")
{
return new DerivedA();
}
else if(msClassName == "DerivedB")
{
return new DerivedB();
}
else if(/*etc...*/)
{
/*etc...*/
}
};
private:
string msClassName;
};
/*etc.*/
Is there a way to somehow convert this string to an actual type (class), so that BaseFactory wouldn't have to know all the possible Derived classes, and have if() for each one of them? Can I produce a class from this string?
I think this can be done in C# through Reflection. Is there something similar in C++?
This is the factory pattern. See wikipedia (and this example). You cannot create a type per se from a string without some egregious hack. Why do you need this?
The short answer is you can't. See these SO questions for why:
Tor Brede Vekterli provides a boost extension that gives exactly the functionality you seek. Currently, it is slightly awkward fitting with current boost libs, but I was able to get it working with 1.48_0 after changing its base namespace.
http://arcticinteractive.com/static/boost/libs/factory/doc/html/factory/factory.html#factory.factory.reference
In answer to those who question why such a thing (as reflection) would be useful for c++ - I use it for interactions between the UI and an engine - the user selects an option in the UI, and the engine takes the UI selection string, and produces an object of the desired type.
The chief benefit of using the framework here (over maintaining a fruit-list somewhere) is that the registering function is in each class's definition (and only requires one line of code calling the registration function per registered class) - as opposed to a file containing the fruit-list, which must be manually added to each time a new class is derived.
I made the factory a static member of my base class.
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns
Meaning reflection as in Java. there is some info here: http://msdn.microsoft.com/en-us/library/y0114hz2(VS.80).aspx
Generally speaking, search google for "c++ reflection"
Nope, there is none, unless you do the mapping yourself. C++ has no mechanism to create objects whose types are determined at runtime. You can use a map to do that mapping yourself, though:
And then you can do
Getting a new instance. Another idea is to have the types register themself:
You could decide to create a macro for the registration
I'm sure there are better names for those two though. Another thing which probably makes sense to use here is
shared_ptr
.If you have a set of unrelated types that have no common base-class, you can give the function pointer a return type of
boost::variant<A, B, C, D, ...>
instead. Like if you have a class Foo, Bar and Baz, it looks like this:A
boost::variant
is like an union. It knows which type is stored in it by looking what object was used for initializing or assigning to it. Have a look at its documentation here. Finally, the use of a raw function pointer is also a bit oldish. Modern C++ code should be decoupled from specific functions / types. You may want to look intoBoost.Function
to look for a better way. It would look like this then (the map):std::function
will be available in the next version of C++ too, includingstd::shared_ptr
.