[Solved] Qt5 qMetaTypeConstructHelper ? (object factory)
-
Is qMetaTypeConstructHelper deprecated in Qt 5. I am trying to use
@template <>
void *qMetaTypeConstructHelper<MyModule>(const MyModule *)
{
return new MyModule();
}int MyModule::s_moduleID = qRegisterMetaType<MyModule>("MyModule");
@i get the following errors during compilation :
MyModule.cpp:17: error: C2143: syntax error : missing ';' before '<'
MyModule.cpp:17: error: C2988: unrecognizable template declaration/definition
MyModule.cpp:17: error: C2059: syntax error : '<'How to get this working ?
-
From Qt 5 "qmetatype.h":http://code.woboq.org/qt5/qtbase/src/corelib/kernel/qmetatype.h.html i found that there is a definition like
@namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
static void Delete(void t)
{
delete static_cast<T>(t);
}static void *Create(const void *t) { if (t) return new T(*static_cast<const T*>(t)); return new T(); } static void Destruct(void *t) { Q_UNUSED(t) // Silence MSVC that warns for POD types. static_cast<T*>(t)->~T(); } static void *Construct(void *where, const void *t) { if (t) return new (where) T(*static_cast<const T*>(t)); return new (where) T; }
....
}
@But its defined in a struct which is under QtMetaTypePrivate namespace, How should i use this ?
-
You shouldn't.
Why do you want to use it in the first place?
-
In the above example "MyModule" class is derived from QFrame, and for my application i need to use a copy constructor , but since the copy constructor is DISABLED in the private section , it always returned "error: C2248: 'QFrame::QFrame' : cannot access private member declared in class 'QFrame'
so in order to use that in Qt 4 i tried to use
@template <>
void *qMetaTypeConstructHelper<MyModule>(const MyModule *)
{
return new MyModule();
}int MyModule::s_moduleID = qRegisterMetaType<MyModule>("MyModule");@
but somehow while porting to Qt 5 the above template is not available i need to find an alternate solution to this.
-
The copy constructor is disabled for a reason (and the template specialization for qMetaTypeConstructHelper does not work as copy constructor; it just creates a <code>new MyModule</code> using the default constructor).
So let's go back another step - why do you need a copy constructor in the first place?
What is the problem you are trying to solve?If you are out for registering a non-copyable type with the meta type system don't, as the meta type system relies on a publicly available copy constructor (which is false for any QObject subclass). If you need to create a QObject by its name use a factory.
-
[quote author="Lukas Geyer" date="1358775900"]
If you are out for registering a non-copyable type with the meta type system don't, as the meta type system relies on a publicly available copy constructor (which is false for any QObject subclass). If you need to create a QObject by its name use a factory.[/quote]You got it right, I actually want to create a QObject by its name, I too agree with using the facory implementation. Now I need to put the factory in place and test.
Thanks for the reply.
-
I did some search and got an implementation of factory pattern :
@#include <QMap>
#include <QString>template<class Base> Base* new_object(const QString&);
template<class Base>
class Factory
{ // singleton class, one each base class
Factory() {}
Factory(const Factory&);
Factory& operator=(const Factory&);
~Factory() { qDeleteAll(creators); }
friend Base* new_object<>(const QString&);
public:
Base* create(const QString& nm) const
{
return (creators.contains(nm) ? creators[nm]->create() : NULL);
}class Creator { public: virtual ~Creator() {} virtual Base* create() const = 0; }; static Factory& instance() { static Factory p_instance; return p_instance; } void unregisterCreator(const QString& nm) { if (creators.contains(nm)) { delete creators[nm]; creators.remove(nm); } } void registerCreator(const QString& nm, const Creator* c) { unregisterCreator(nm); creators.insert(nm, c); }
private:
QMap<QString, const Creator*> creators;
};template<class Base> Base* new_object(const QString& nm)
{
return Factory<Base>::instance().create(nm);
}template<class Derived, class Base> class Register
{
typedef Derived* (*CreateFn) ();class Creator : public Factory<Base>::Creator { public: Creator(CreateFn fn) : createFn(fn) {} virtual Derived* create() const { return (createFn ? createFn() : new Derived(NULL)); } CreateFn createFn; };
public:
Register(const QString& nm, CreateFn fn = NULL)
{
Factory<Base>::instance().registerCreator(nm, new Creator(fn));
}
};@To create an instance we can use
@Factory<QObject>::instance().create("RegisterMe")@
or
@QObject *o = new_object<QObject>("RegisterMe");@
See "Simple-yet-powerful-object-factory":http://www.qtcentre.org/threads/8714-Simple-yet-powerful-object-factory
There is another implementation provided by you at "Elegant factory design":http://qt-project.org/forums/viewthread/21540 discussion.