What does the Q_OBJECT macro do? Why do all Qt objects need this macro?
From the Qt documentation:
The Meta-Object Compiler, moc, is the
program that handles Qt's C++
extensions.The moc tool reads a C++ header file.
If it finds one or more class
declarations that contain the Q_OBJECT
macro, it produces a C++ source file
containing the meta-object code for
those classes. Among other things,
meta-object code is required for the
signals and slots mechanism, the
run-time type information, and the
dynamic property system.
Do I need to use the Q_OBJECT macro if I only use slots?
From Qt QObject class reference:
Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties.
Q_OBJECT and moc for inheritance
The presence of the Q_OBJECT
macro marks the class for inclusion in Qt's meta-object system. If you want your class to have its own identity in this meta-object system, you must put the Q_OBJECT
macro into it (and make sure it is directly or indirectly derived from QObject
, naturally).
In your case of cBaseObject
and cEnhancedbaseObject
, if cEnhancedbaseObject
does not include the Q_OBJECT
macro, it will still work normally. However, as far Qt's meta-object system is concerned, objects of type cEnhancedbaseObject
will be of meta-type cBaseObject
. You can see that using such functions as myObject->metaObject()->className()
.
When should Q_OBJECT be used?
You should use the Q_OBJECT
macro for any non-templated classes that derive from QObject
.
Besides signals and slots, the Q_OBJECT
macro provides the meta object information that is associated with given class.
As stated in the documentation:
we strongly recommend that all subclasses of QObject use the Q_OBJECT macro regardless of whether or not they actually use signals, slots, and properties.
Suppose we have the following class:
class Class : public QObject {
public:
Class() {}
};
Without Q_OBJECT
, the following metaobject system features (among others) will not work for Class
:
qobject_cast<Class>()
- due to missing metadataQObject::tr()
- due to missing metadataslots and invokables first declared in
Class
, when invoked or looked up by name - none ofQMetaObject
methods will work for these methods, neither will the Qt 4connect
- due to missing metadatasignals - since
moc
won't generate their implementations and the code won't compile.
You can omit it, of course, but if you ever use these features, you'll need to remember to put the macro into the class's declaration. This is a rather brittle practice and best avoided. The savings are not worth it. So, don't wait - add the Q_OBJECT
macro to every class that derives from QObject
as a matter of coding policy.
The Q_OBJECT
macro should never be used on classes that don't derive from QObject
. To add invokables and properties to such classes, use the Q_GADGET
macro instead.
Q_OBJECT macro and meta-object code
Meta objects enhance programming languages by creating new or manipulate existing objects. They provide functionalities a language does not actually have by itself. The Meta Objects are interpreted either by compile time or run time. In Qt and C++ it is done during compile time by the Meta Object Compiler (moc).
An example case is the usage of the signal/slot concept.
c++ macro containing Q_OBJECT
It turns out that as suggested by @Silicomancer you cannot as it is.
I figured out that the proble was the multi-line macro and it works indeed if the macro is one-line:
#define MY_PLUGIN_BASE(__c_name,__appendix) class __c_name##__appendix : public QObject, myPlug { Q_OBJECT Q_INTERFACES(nPanPlug) Q_PLUGIN_METADATA(IID "org.myapp.plug") public: __c_name##__appendix() {qRegisterMetaType<__c_name *>(#__c_name"*");} QByteArray name() {return #__c_name;} };
To me it looks like moc goes through the file looking for Q_OBJECT
but doesn't mess with macros
Related Topics
Memory Stability of a C++ Application in Linux
Fast String Hashing Algorithm with Low Collision Rates with 32 Bit Integer
C++: Simple Return Value from Std::Thread
Why Unsigned Int 0Xffffffff Is Equal to Int -1
Implementing Sse 4.2's Crc32C in Software
Long Long Int VS. Long Int VS. Int64_T in C++
Why Are Python Programs Often Slower Than the Equivalent Program Written in C or C++
Making Std::Vector Allocate Aligned Memory
Checking for an Empty File in C++
How to Convert a C++ String to an Int
Effective C++ Item 23 Prefer Non-Member Non-Friend Functions to Member Functions
C++: Can a MACro Expand "Abc" into 'A', 'B', 'C'
How to Write a Type Trait 'Is_Container' or 'Is_Vector'
How to Read the Results of a System() Call in C++
String Conversion with Boost Locale: Different Behaviour on Windows and Linux