I am using a class factory to create objects dynamically. I used this answer for its simplicity (and because I am using Qt).
But now I realize I must add an argument to my constructor
Item(bool newItem /* = true*/);
instead of
Item();
for the code in the referred answer:
template <typename T>
class ClassFactory
{
public:
template <typename TDerived>
void registerType(QString shape)
{
_createFuncs[shape] = &createFunc<TDerived>;
}
T* create(QString shape)
{
typename QMap<QString, PCreateFunc>::const_iterator it = _createFuncs.find(shape);
if (it != _createFuncs.end())
{
return it.value()();
}
return NULL;
}
private:
template <typename TDerived>
static T* createFunc()
{
return new TDerived();
}
typedef T* (*PCreateFunc)();
QMap<QString, PCreateFunc> _createFuncs;
};
I registered the class
classFactory.registerType <Type1_Item> ("type1");
when needed, I called
Item* item = classFactory.create("type1");
I am trying to add an additional argument in the class factory, to represent the constructor argument, but my attempts all result in error.
Why do I need it : simple case:
create a new object - sets defaults; for certain objects, it requires an open file dialog since data has to be loaded from a file.
load an object - fills data, including the filename for objects that contain file info
To be able to call the "load" function, an object must exist - which means that if I create a new object, I will trigger an open file dialog even though I do not need it.
The work around that I see is, to have a constructor followed by a setup function. But... that means constructing an object always requires a 2-function call, which seems like bad design.
that is why I am looking for a way to register and call the classes using simple calls like
classFactory.registerType <Type1_Item> ("type1", bool);
Item* item = classFactory.create("type1", true);
Is it possible, and how can I do it ?
You may use this modified version
template <typename T, typename ... Ts>
class ClassFactory
{
public:
template <typename TDerived>
void registerType(QString shape)
{
_createFuncs[shape] = &createFunc<TDerived>;
}
T* create(QString shape, Ts... args)
{
typename QMap<QString, PCreateFunc>::const_iterator it = _createFuncs.find(shape);
if (it != _createFuncs.end())
{
return it.value()(args...);
}
return nullptr;
}
private:
template <typename TDerived>
static T* createFunc(Ts... args)
{
return new TDerived(args);
}
typedef T* (*PCreateFunc)(Ts...);
QMap<QString, PCreateFunc> _createFuncs;
};
And use it
ClassFactory<Item, bool> classFactory;
classFactory.registerType <Type1_Item> ("type1");
Item* item = classFactory.create("type1", true);