QtQObject

Remarks

QObject class is the base class for all Qt objects.

QObject example

Q_OBJECT macro appears in private section of a class. Q_OBJECT requires the class to be subclass of QObject. This macro is necessary for the class to declare its signals/slots and to use Qt meta-object system.

If Meta Object Compiler (MOC) finds class with Q_OBJECT, it processes it and generates C++ source file containing meta object source code.

Here is the example of class header with Q_OBJECT and signal/slots:

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT

public:

public slots:
    void setNumber(double number);        

signals:
    void numberChanged(double number);

private:
} 

qobject_cast

T qobject_cast(QObject *object)

A functionality which is added by deriving from QObject and using the Q_OBJECT macro is the ability to use the qobject_cast.

Example:

class myObject : public QObject
{
    Q_OBJECT
    //...
};

QObject* obj = new myObject();

To check whether obj is a myObject-type and to cast it to such in C++ you can generally use a dynamic_cast. This is dependent on having RTTI enabled during compilation.

The Q_OBJECT macro on the other hands generates the conversion-checks and code which can be used in the qobject_cast.

myObject* my = qobject_cast<myObject*>(obj);
if(!myObject)
{
    //wrong type
}

This is not reliant of RTTI. And also allows you to cast across dynamic library boundaries (via Qt interfaces/plugins).

QObject Lifetime and Ownership

QObjects come with their own alternative lifetime concept compared to native C++'s raw,unique or shared pointers.

QObjects have the possibility to build an objecttree by declaring parent/child relationships.

The simplest way to declare this relationship is by passing the parent object in the constructor. As an lternative you can manually set the parent of a QObject by calling setParent. This is the only direction to declare this relationship. You cannot add a child to a parents class but only the other way round.

QObject parent;
QObject child* = new QObject(&parent);

When parent now gets deleted in stack-unwind child will also be deleted.

When we delete a QObject it will "unregister" itself form the parent object;

QObject parent;
QObject child* = new QObject(&parent);
delete child; //this causes no problem.

The same applies for stack variables:

QObject parent;
QObject child(&parent);

child will get deleted before parent during stack-unwind and unregister itself from it's parent.

Note: You can manually call setParent with a reverse order of declaration which will break the automatic destruction.