解析Qt內省機制

2021-08-19 22:05:45 字數 3827 閱讀 3105

所謂內省是指物件導向語言的一種在執行期間查詢物件資訊的能力, 比如如果該語具有執行期間檢查物件型別的能力,那麼我們稱它是型別內省(type intropection)的,型別內省可以用來實施多型。

c++的內省比較有限,它僅支援上面所說的型別內省, c++的型別內省是通過執行時型別識別(rtti)(run-time type information)中的typeid以及dynamic_case關鍵字來實現的,舉例說明:

// rabbit 派生於 animal, jump為虛函式  

if ( rabbit *p = dynamic_case(obj))

//我們還可以通過typeid萃取到物件的型別資訊,比如物件的名稱

std::cout

<< typeid(obj).name() << std::endl

qt拓展了c++的內省機制,(實際上,它並沒有採用c++的rtti),而是提供了更為強大的元物件(meta object)機制,來實現內省。接下來,就讓我們看看,qt是如何擴充套件c++內省機制的。

要深刻理解qt的內省機制,首先理解qobjectqobject類是整個qt物件模型的心臟,qt物件模型最為核心的功能是提供一種無縫的物件通訊機制,即就是我們所熟知的訊號和槽。qobject主要有三大職責: 記憶體管理、內省(intropection)與事件處理。本文將集中在在內省的討論。以下**介紹了qobject類提供的內省方法:

//每個物件可以通過qobject::setobjectname()和qobject::objectname()設定、取得類的例項的名字   

obj.setobjectname("instancename");

qstring name1 = obj.objectname(); // return instancename

//每個物件還可以通過它的元物件classname方法得到類的名字

//每個物件可以通過qobject::inherits方法來查詢是否對前物件類派生於量乙個類

bool isherited = obj.inherits("qobject"); // returns true

isherited = obj.inherits("qwideget"); // returns true

讓我們再來一下qobject::inherits方法的底層實現:

inline

bool inherits(const

char *classname) const

原來,qobject::inherits是通過qt_metacast()這個虛函式實現的, 事實上每個qobject的派生類都必須實現metaobject()以及其他qt_metacall()方法,從而滿足自省方法classname,inherits等方法的呼叫(當然還有其他用途)。

而所有有關派生從qobject的子類中的內省方法無須有使用者實現,使用者只要在類中宣告巨集q_object即可,qt的元物件編譯器(moc)負責實現派生qobject的子類中的內省方法。

// defined at ..\qt\src\corelib\kernel\qobjectdefs.h   

/* tmake ignore q_object */

#define q_object \

public: \

q_object_check \

static

const qmetaobject staticmetaobject; \

q_object_getstaticmetaobject \

virtual

const qmetaobject *metaobject() const; \

virtual

void *qt_metacast(const

char *); \

qt_tr_functions \

virtual

int qt_metacall(qmetaobject::call, int, void **); \

此外,所有的qt widgets類均繼承自qobject,qobject所提供的iswidgettype自省方法可以很方便讓qobject子物件查詢自己是否是wideget, 而且它會比qobject_cast(obj)或者obj->inherits快很多。原因qobject_cast()inherits()都是借助元物件系統來實現其功能的,iswidgettype()qobject本身的標誌位得以實現。

struct

q_core_export qmetaobject

上述方法主要是實現對元物件表的訪問及其操作,元物件表(由moc實現)例項如下所示:

// defined at ..\qt\src\corelib\kernel\qobjectdefs.h   

/* tmake ignore q_object */

#define q_object \

public: \

q_object_check \

static

const qmetaobject staticmetaobject; \

q_object_getstaticmetaobject \

virtual

const qmetaobject *metaobject() const; \

virtual

void *qt_metacast(const

char *); \

qt_tr_functions \

virtual

int qt_metacall(qmetaobject::call, int, void **); \

qt是通過qobjectqmetaobject類實現其內省機制,

qobject暴露給使用者的共有自省方法有objectname(),inherits()iswidgettype()

大多數自省方法是qobject派發給qmetaobject實現 (e.g.qmetaobject::classname),元物件模型編譯器moc負責自省方法的實現

4、更多自省方法定義在qmetaobject,是為了訊號槽通訊、事件派發等機制

QT內省機制 自定義Model 資料庫

本文將介紹自定義model過程中資料庫資料來源的獲取方法,我使用過以下三種方式獲取資料庫資料來源 本文重點介紹第二種,即利用qt的內省機制來獲取資料。1.自定義model過程 通過內省功能獲得字段值,也就是第二種方法 本文中自定義model繼承於qabstracttablemodel 重點描述set...

通過內省機制設定JavaBean

一 步驟 1 使用propertydescriptor類獲取屬性描述者物件 pd引用student的name屬性 propertydescriptor pd new propertydescriptor name student.class 2 通過getwritemethod 方法 invoke ...

01 Introspector內省機制

在j a領域程式設計中,內省機制相當的不錯,可以省去我們程式設計師很多的不必要的 比如說 在jdbc工具類 我們可以將resultset結果集待到 j abean物件中 將http請求報文的資料 轉換到乙個 j abacn物件當中去 這樣子可以省去我們很多的 request.getparameter...