Une alternative aux modèles est d'utiliser une fermeture lambda avec C++ 11. Voici ma préférence.
// in header file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator);
// in source file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator) {
// Some processing. Perhaps the interface_params are generated
// inside this function instead of being passed to it.
IClass * mCls = cls_allocator(interface_params);
// Do whatever with mCls
return mCls;
}
// Somewhere else in the code.
{
Param1Type param1 = whatever1;
Param2Type param1 = whatever2;
// param1, param2, etc. are parameters that only
// SomeClsDerivedFromIClass constructor knows about. The syntax ¶m1
// achieves the closure.
// interface_param1 is common to all classes derived from IClass.
// Could more than one parameter. These parameters are parameters that
// vary from different calls of MyFunctionThatDoesStuff in different
// places.
auto cls_allocator =
[¶m1, ¶m2](const IParams & interface_params)->IClass * {
return new SomeCls1DerivedFromIClass(interface_params,
param1, param2);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
// Somewhere else in the code again.
{
ParamXType paramX = whateverX;
ParamYType paramY = whateverY;
auto cls_allocator =
[¶mX, ¶mY](const IParams & interface_params)->IClass * {
return new SomeCls2DerivedFromIClass(interface_params,
paramX, paramY);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
L'idée de code ci-dessus fonctionne bien pour un motif de construction rapide ou une variation de motif d'usine. Le lambda est essentiellement une méthode d'usine. Pour le rendre encore plus dynamique, vous pouvez utiliser la saisie automatique des paramètres. Quelque chose comme ça. J'arrive à ceci de l'influence de Python où vous pouvez simplement passer le type de classe à la fonction.
@Martin, c'est une définition intéressante de "relativement nouveau", compte tenu du fait que Smalltalk, qui était assez courant en son temps, et qui contenait pas mal de code, ne l'a fait que dans les années 70 :) –
choses attribuées à Smalltalk, Lisp était là dans les années 1950 - l'ensemble du programme était une infrastructure de données qui pouvait être inspectée et manipulée. –