[Interest] How to create QObject-derived class instance from class name

Nye kshegunov at gmail.com
Wed Mar 2 21:27:47 CET 2016


> You can either use QMetaType for that or your own registration/factory.
Thiago,
Yes, that's exactly true. I just decided to use QMetaType, as Qt already
provides the registration/creation infrastructure, instead of pushing a
factory object to the library that will create the instances (or using my
own implementation of runtime registration). My intention was not, however,
to hijack Sina's thread, so I'll stop with that here.

> Ah you mean by "knowing types at compile time" is actually defined types,
so you actually defining classes at run-time?
Sina,
No, I didn't mean that. You can't define classes at runtime as C++ is not a
dynamic language. I had an issue similar to your own - I wanted to write an
object to a byte array, send it through the network, and then recreate the
object at the other end. So one option is to have a factory class that know
every possible object that can be send, writes a number or a string, then
the object writes its data; send it through the network and at the other
end - read the number/string, create the object and then call the function
on that object (typically a virtual one) that reads the object's data. The
thing is, for me this whole write-send-read thing is in a dynamic library
and the classes that are serialized/deserialized are defined in the user
application, so the library doesn't know in advance what possible classes
the user might have defined, only that they have a common ancestor. So
instead of making my own registration, I used Qt's QMetaType class.

Long story short:
When I have to serialize the object, I'm retrieving the appropriate
QMetaObject, getting the class name from it and then I'm using
QMetaType::type to retrieve the corresponding meta-type id. This integer I
write in the byte stream, and then, I'm calling the object's virtual
serialize method with the byte array (so it can write its data).
On the other end I'm reading the integer, checking if this meta-type id is
registered with QMetaType::isRegistered and then I'm using
QMetaType::create with said meta-type id to create the correct instance.
I'm casting the void * that the creation method returns to a base class
pointer and calling the virtual deserialize method (so the object can read
it's data).

Here's a thread I started in the Qt forum some time ago, which could be
useful if you decide to have your objects marshaled in a similar manner:
https://forum.qt.io/topic/64277/meta-type-id-of-an-object

I hope that helps.
Kind regards.




On Wed, Mar 2, 2016 at 5:51 PM, Thiago Macieira <thiago.macieira at intel.com>
wrote:

> On quarta-feira, 2 de março de 2016 13:04:35 PST Nye wrote:
> > I just meant that in my case the classes are defined in the user
> > application, so the library has no notion whatsoever what classes it has
> > available to create instances from and it depends on the meta-type system
> > exclusively for that (while still handling the
> > serialization/deserialization of said instances). It just makes a factory
> > inapplicable in my case (at least if you're not counting the meta-type
> > system as a factory).
>
> You don't know the list when you write the code, but you do know the list
> at
> runtime. The full set of classes that can be instantiated needs to be
> registered with a central authority.
>
> You can either use QMetaType for that or your own registration/factory.
>
> But it needs to be done.
>
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
>   Software Architect - Intel Open Source Technology Center
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20160302/bfc0d21e/attachment.html>


More information about the Interest mailing list