Qt元對象系統簡介

目錄

1.基本介紹

2.Q_OBJECT

3.元對象系統與反射機制

4.qobject_cast 函數


1.基本介紹


元對象:是指用於描述另一個對象結構的對象。使用編程語言具體實現時,其實就是一個類的對象,只不過這個對象專門用於描述另一個對象而已。

Qt 的元對象系統提供的功能有:對象間的通信、運行時類型信息和動態屬性系統等

元對象系統的實現需要滿足以下三個條件:

  1. 該類必須繼承自 QObject
  2. 必須在類聲明的私有區域添加 Q_OBJECT 宏,該宏用於啓動元對象特性,然後便可使用動態特性、信號和槽等功能了
#include <QObject>

class A{};

class B:public QObject,public A
{
    Q_OBJECT
};

劃重點:要使用元對象系統必須繼承自 QObject 類,且 QObject 應位於基類繼承列表中的第一位,Q_OBJECT 必須位於私有區域

2.Q_OBJECT


QObject宏定義如下:

#define Q_OBJECT \
public: \
    Q_OBJECT_CHECK \
    QT_WARNING_PUSH \
    Q_OBJECT_NO_OVERRIDE_WARNING \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
    QT_TR_FUNCTIONS \
private: \
    Q_OBJECT_NO_ATTRIBUTES_WARNING \
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    QT_WARNING_POP \
    struct QPrivateSignal {}; \
    QT_ANNOTATE_CLASS(qt_qobject, "")

/* qmake ignore Q_OBJECT */
#define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "")

裏面的QMetaObject 類描述了 QObject 及其派生類對象的所有元信息,該類是 Qt 元對象系統的核心類,通過該類的成員函數可以獲取 QObject 及其派生類對象的所有元信息,因此可以說 QMetaObject 類的對象是 Qt 中的元對象 

3.元對象系統與反射機制


reflection 模式(反射模式或反射機制):是指在運行時,能獲取任意一個類對象所有類型信息、屬性、成員函數等信息的一種制 

使用 Qt 反射機制的條件:

  1. 註冊成員函數:若希望普通成員函數能夠被反射,需要在函數聲明之前加入QObject::Q_INVOKABLE 宏
  2. 註冊成員變量:若希望成員變量能被反射,需要使用 Q_PROPERTY 宏
#include <QObject>
#include <iostream>
#include <QMetaMethod>
#include <QByteArray>
#include <QMetaObject>

using namespace std;

class A {};

class B :public QObject, public A   //多繼承時,QObject必須放在第一個繼承
{
	Q_OBJECT

public:
	 Q_INVOKABLE B(){}  //要想函數被反射,需要指定 Q_INVOKABLE 宏
	 Q_INVOKABLE B(int){}
	 Q_INVOKABLE void f1(){}
	void f2() {}         //注意:此函數不會被反射

signals:
	void signal1();
};

class C :public B
{
public:
	Q_INVOKABLE void f3() {}
signals:
	void signal3();
};

int main()
{
    B pB;C pC;
    const QMetaObject *pMetaObjB = pB.metaObject();  //獲取B類元對象
    const QMetaObject *pMetaObjC = pC.metaObject();  //獲取C類元對象

    //返回對象成員函數數量
    std::cout << "類B的成員函數:" << pMetaObjB->methodCount() << std::endl; 
    std::cout << "類C的成員函數:" << pMetaObjC->methodCount() << std::endl;
    
    //獲取對象 B所屬類中的構造函數的數量
    std::cout << "類B的構造函數:" << pMetaObjB->constructorCount() << std::endl;
}

QMetaObject 元對象類裏面包含多種相關的方法,可以在此類中根據需要進行使用。

 

4.qobject_cast 函數


使用語法:DestType* qobject_cast<DestType*>(QObject *p);

特性:

  1. 該函數類似於 C++中的 dynamic_cast,但執行速度比 dynamic_cast 更快;
  2. qobject_cast 僅適用於 QObject 及其派生類;
  3. 主要作用是把源類型 QObject 轉換爲尖括號中的目標類型 DesType(或者子類型),並返回指向目標類型的指針,若轉換失敗,則返回 0;
  4. 使用 qobject_cast 的條件:目標類型 DestType 必須繼承(直接或間接)自 QObject,並使用 Q_OBJECT 宏。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章