I would like to initialize 2 classes(say Class ARegister, Class BRegister) that registers some values(A,B). I want to initialize these two classes from a super(?) class( say Cla
the best way do to this is using CRTP (curiously recurring template pattern), the derived classes ARegister and BRegister pass themselves as template arguments to the base class RegisterALL. It will look like this:
class RegisterAll
{
public:
template
DerivedType *createType()
{
RegisterAll *r = (*(m_creators[DerivedType::id]))();
return dynamic_cast(r); //static_cast will work too if you didn't make a mistake
}
protected:
static std::map m_creators;
};
std::map RegisterAll::m_creators = std::map();
template
class CRTPRegisterAll : public RegisterAll
{
public:
static bool register()
{
RegisterAll::m_creators.push_back(std::make_pair(Derived::id,Derived::create);
return true;
}
private:
static bool m_temp;
};
template
bool CRTPRegisterAll::m_temp = CRTPRegisterAll::register();
class RegisterA : public CRTPRegisterAll
{
private:
static RegisterA *create()
{
//do all initialization stuff here
return new RegisterA;
}
public:
static const int id = 0;
};
Now the initialization of the static variable m_temp
in CRTPRegisterAll
pushes a creator function for each derived type onto RegisterAll
's list. It is generally not very good design to have RegisterAll
know about all the derived classes (it isn't very extensible). This way the actual creation method can be implemented in each derived class and the creator function will be automatically registered in RegisterAll
. One of the main advantages of CRTP is that the derived classes don't need to know how to register themselves to the base class' list, it is done for them. As for error handling that too can be implemented in each derived class' creator functions. There are better ways to handle the id issue but I don't want to get into that here.
If you want a simpler method I suggest reading about the Factory design pattern.