#include <QLabel>
#include <QObject>
#include <QTimer>
/* Works both with Qt3 and Qt4. No fancy Qt meta object info used,
* no QOBJECT macro or other specific Qt stuff. No derivation from
* Qt classes used. The only (easily portable) requirements are for
* a QMap and a QString, all remaining stuff is pure C++ with no
* other libraries involved. Finally no namespace pollution, only
* Register<> and Factory<> templates are visible.
*/
#include "factory.h" // just need to include this header
/* First (and only) thing to do is to 'register' a class with a proper factory
* in one IMPLEMENTATION FILE (not header!). You can choose any file you
* want as long as a declaration of your class is included.
* Probably you may want to register the class at the beginning of the file
* that implements your class, but this is up to you.
*
* The first name in 'Register' template instantation is the class to
* register, the second one is the base class of our hierarchy. We can
* have more hierarchies at the same time.
*
* We can register a class with a factory anywhere in a program, both in file
* scope (will be registered at startup with static data), as we see here, or
* in a function body (will be registered when the function is called).
*/
// teach QWidget's factory how to create a QLabel
static Register<QLabel, QWidget> l("QLabel");
// teach QObject's factory how to create a QTimer
static Register<QTimer, QObject> t("QTimer");
/* Of course you can (better) use an anonymous namespace in
* implemantation files to avoid the 'static' qualifier
*/
namespace {
// no problem in re-registering the same class, old one will be overwritten
Register<QTimer, QObject> w("QTimer");
// we can (optionally) provide our custom 'create' function, see later
QLabel* customCreator
() { return new QLabel("Function customCreator() was used");
} }
int main(int argc, char* argv[]) { // this simple driver program requires Qt4
// now we can start creating objects, as example a QTimer
QObject* t
= Factory<QObject>
::instance().
create("QTimer");
if (dynamic_cast<QTimer*>(t)) qDebug("It's a timer"); // Yes. It is!
// we can use any string expression to pass the class name to our factory
QWidget* lbl
= Factory<QWidget>
::instance().
create("Q" + myName
);
qDebug("Class of lbl is %s", lbl->metaObject()->className()); // Yes. It's a QLabel
{ // local scope here, could be any function body
// we can use any alias when registering a class with a factory,
// in this case we call 'myObject' a QObject class
Register<QObject, QObject> localVar("myObject");
} // variable 'localVar' goes out of scope here and is deleted...
// ...but we can still create a "myObject" object anywhere in the program
QObject* obj
= Factory<QObject>
::instance().
create("myObject");
qDebug("Class of obj is %s", obj->metaObject()->className()); // it's a QObject
// we can always redefine an object creator, as example using our
// custom one instead of the default supplied...
Register<QLabel, QWidget> dummy("QLabel", &customCreator);
// ...so that any new QLabel will be created with our
// customCreator() function
QLabel* lbl2
= dynamic_cast<QLabel
*>
(Factory<QWidget>::instance().create("QLabel"));
// "Function customCreator() was used"
qDebug("%s", lbl2->text().toLatin1().constData());
delete t; // objects can be deleted as usual when no more needed
delete lbl;
delete obj;
delete lbl2;
return 0;
}
#include <QLabel>
#include <QObject>
#include <QTimer>
/* Works both with Qt3 and Qt4. No fancy Qt meta object info used,
* no QOBJECT macro or other specific Qt stuff. No derivation from
* Qt classes used. The only (easily portable) requirements are for
* a QMap and a QString, all remaining stuff is pure C++ with no
* other libraries involved. Finally no namespace pollution, only
* Register<> and Factory<> templates are visible.
*/
#include "factory.h" // just need to include this header
/* First (and only) thing to do is to 'register' a class with a proper factory
* in one IMPLEMENTATION FILE (not header!). You can choose any file you
* want as long as a declaration of your class is included.
* Probably you may want to register the class at the beginning of the file
* that implements your class, but this is up to you.
*
* The first name in 'Register' template instantation is the class to
* register, the second one is the base class of our hierarchy. We can
* have more hierarchies at the same time.
*
* We can register a class with a factory anywhere in a program, both in file
* scope (will be registered at startup with static data), as we see here, or
* in a function body (will be registered when the function is called).
*/
// teach QWidget's factory how to create a QLabel
static Register<QLabel, QWidget> l("QLabel");
// teach QObject's factory how to create a QTimer
static Register<QTimer, QObject> t("QTimer");
/* Of course you can (better) use an anonymous namespace in
* implemantation files to avoid the 'static' qualifier
*/
namespace {
// no problem in re-registering the same class, old one will be overwritten
Register<QTimer, QObject> w("QTimer");
// we can (optionally) provide our custom 'create' function, see later
QLabel* customCreator() { return new QLabel("Function customCreator() was used"); }
}
int main(int argc, char* argv[]) { // this simple driver program requires Qt4
QApplication app(argc, argv);
// now we can start creating objects, as example a QTimer
QObject* t = Factory<QObject>::instance().create("QTimer");
if (dynamic_cast<QTimer*>(t)) qDebug("It's a timer"); // Yes. It is!
// we can use any string expression to pass the class name to our factory
QString myName = "Label";
QWidget* lbl = Factory<QWidget>::instance().create("Q" + myName);
qDebug("Class of lbl is %s", lbl->metaObject()->className()); // Yes. It's a QLabel
{ // local scope here, could be any function body
// we can use any alias when registering a class with a factory,
// in this case we call 'myObject' a QObject class
Register<QObject, QObject> localVar("myObject");
} // variable 'localVar' goes out of scope here and is deleted...
// ...but we can still create a "myObject" object anywhere in the program
QObject* obj = Factory<QObject>::instance().create("myObject");
qDebug("Class of obj is %s", obj->metaObject()->className()); // it's a QObject
// we can always redefine an object creator, as example using our
// custom one instead of the default supplied...
Register<QLabel, QWidget> dummy("QLabel", &customCreator);
// ...so that any new QLabel will be created with our
// customCreator() function
QLabel* lbl2 = dynamic_cast<QLabel*>
(Factory<QWidget>::instance().create("QLabel"));
// "Function customCreator() was used"
qDebug("%s", lbl2->text().toLatin1().constData());
delete t; // objects can be deleted as usual when no more needed
delete lbl;
delete obj;
delete lbl2;
return 0;
}
To copy to clipboard, switch view to plain text mode
Bookmarks