Unsolved How to query for registered interfaces?
-
Hey all,
I'm testing out the capabilities of Qt's meta data. There is a Q_DECLARE_INTERFACE macro for registering an interface with Qt, and a Q_INTERFACES macro for specifying what interfaces a given class implements.
I know how to query for interfaces that a specific class implements, via its QMetaObject.What I'd like to do, however, is obtain the list of all registered interfaces and spit out the class name + identifier that they were registered with. Does anyone know how to do this?I don't have a particular application in mind just yet, but would like to know the extents of what I can do with the Qt Object Model. So far I like all that it adds, but definitely not quite as powerful as .NET reflection. For instance, .NET allows you to associate attributes with a class, method, property, etc. But Qt only has the generic "class_info" construct.
Thanks!
EDIT: I assumed you could easily get an objects implemented interfaces via the QMetaObject. However, looking again, there doesn't appear to be any way of accessing the interfaces there?! So in addition to how to query all registered interfaces, how do I query for the interface list that a particular QObject implements? Thanks again!
-
@iam1me said in How to query for registered interfaces?:
What I'd like to do, however, is obtain the list of all registered interfaces and spit out the class name + identifier that they were registered with.
Why?
So in addition to how to query all registered interfaces
You don't.
, how do I query for the interface list that a particular QObject implements?
You don't.
What would be the point of having polymorphic classes if you know all about their hierarchy? This would defeat the purpose of having
qobject_cast
/dynamic_cast
, wouldn't it? -
@kshegunov - one application where I would like to use the interface information for is for Dependency Injection. If you take a look at DI containers like Unity for C#, you can inject a concrete implementation of an interface. For instance, If I had a ICache interface with concrete implementations VolatileCache and PersistentCache, I could configure my DI container to use one or the other. Then if it encountered a constructor like below, the DI container would construct the class using the specified cache implementation:
SettingsManager( ICache cache ) {...}
Now, I could accomplish this by creating a concrete base QObject called ICache - but that is inefficient and not very clean code. QObjects are much bulkier than a pure virtual interface class, and I don't like the idea of being able to instantiate an instance of what is supposed to be an interface. Much better would to be able to recognize that the parameter is a registered interface. I also need to validate that the registered implementation class implements said interface. I need to do this with just the class identifiers and not with instances - meaning the casting methods aren't solutions.
It maybe that this is simply a limitation of the Qt framework, a lack of interface meta data.
-
@iam1me Why do you think you would need to use QObject derived classes?
ICache can be pure virtual class without inheriting QObject. Then derive from ICache and implement concrete versions. Then you pass the version you need as parameter to SettingsManager. I don't see any need for reflection for this case. -
@jsulm - I think you misunderstood me. I was not claiming one had to derive from a QObject to have an interface. Qt didn't invent the concept of interfaces in c++.
However, in order to implement a DI container that allows you to dynamically register concrete implementations for interfaces, you need to be able to interact with meta data concerning interfaces. Consider the constructor parameter: how, using Qt's existing meta data framework, can I know that it is an interface? If the parameter was a QObject then there would be a QMetaObject. If it was a structural type then you could register a QMetaType. However, there is no QMetaInterface class as far as I can tell - so there is no way to register or invoke such a constructor with Qt's metadata.
And the only way to automate dynamic DI in the first place is through metadata. The systems needs to be able to access meta data about the constructor of a class it wants to resolve: how many parameters are there, what are the data types? This is why you don't see any common DI containers in C++ like you do in higher level languages like C# and Java: c++ doesn't provide you with all that nice metadata needed to construct such a system. Not to say there have been no attempts at making a DI container in c++, but they aren't anywhere near as powerful and thus lose their appeal. However, Qt modifies the compilation process to generate a lot of meta data to support its services - like its signals and slots. As such I was hoping there would be sufficient metadata to implement a DI container w/ support for interfaces. I was able to get it to work for QObjects, but, again, there seems to be insufficient meta data to support the injection of interfaces.