Qt文档阅读笔记-The Meta-Object System解析及实例
目錄
官方解析
博主栗子
關(guān)于QMetaObject::className()的栗子
官方解析
Qt元對(duì)象系統(tǒng)提供了信號(hào)與槽機(jī)制,通過(guò)信號(hào)與槽實(shí)現(xiàn)對(duì)象間的通信,RTTI,以及動(dòng)態(tài)屬性系統(tǒng)。
meta-object系統(tǒng)是基于下面這3個(gè)東西創(chuàng)建出來(lái)的:
1.以QObject類(lèi)作為其他類(lèi)的基類(lèi),這樣才可以使用meta-object系統(tǒng)。
2.Q_OBJECT宏放在類(lèi)的私有部分,這個(gè)宏可以帶來(lái)meta-object的特征,比如動(dòng)態(tài)屬性,信號(hào)與槽;
3.Meta-object Compiler(moc)為每一個(gè)QObject的子類(lèi)提供實(shí)例元對(duì)象特征所需要的代碼;
moc工具去讀取C++源文件。如果他發(fā)現(xiàn)有一個(gè)或多個(gè)類(lèi)帶有Q_OBJECT這個(gè)宏,那么這些C++源文件就會(huì)生成一個(gè)包含meta-object代碼的.cpp文件。生產(chǎn)出來(lái)的源文件也包含以前的#include,以及他們的成員函數(shù)所連接的實(shí)例。
除此之外還提供了信號(hào)與槽機(jī)制,這個(gè)機(jī)制負(fù)責(zé)兩個(gè)對(duì)象之間的交流(信號(hào)與槽主要的功能就是這個(gè)),meta-object代表提供了下面的額外的功能:
1.QObject::metaObject()返回這個(gè)類(lèi)被關(guān)聯(lián)的meta-object(元對(duì)象);
2.QMetaObject::className()返回在運(yùn)行時(shí)的類(lèi)名,這個(gè)不需要C++編譯器通過(guò)詢問(wèn)RTTI的;
3.QObject::inherits()這個(gè)函數(shù)返回這個(gè)對(duì)象是否是某個(gè)類(lèi)的實(shí)例,并且這個(gè)類(lèi)繼承于QObject繼承樹(shù)中的某一個(gè)類(lèi);
4.QObject::tr()和QObject::trUtf8()把字符串轉(zhuǎn)化為國(guó)際化字符串;
5.QObject::setProperty()和QObject::property()通過(guò)名字動(dòng)態(tài)獲取和設(shè)置屬性;
6.QMetaObject::newInstance()創(chuàng)造了這個(gè)類(lèi)的新實(shí)例;
可以使用qobject_cast()在一個(gè)QObject派生類(lèi)上進(jìn)行動(dòng)態(tài)轉(zhuǎn)化。qobject_cast()這個(gè)函數(shù)的功能和標(biāo)準(zhǔn)C++中的dynmaic_cast()函數(shù),這個(gè)的優(yōu)勢(shì)是他不需要RTII的支持,并且他還是跨平臺(tái)的。他把轉(zhuǎn)化為尖括號(hào)中指定的參數(shù),如果是正確的就返回非零的指針(這個(gè)是在運(yùn)行的時(shí)候確定),如果不正確就返回零給這個(gè)指針。
舉個(gè)栗子,假設(shè)MyWidget繼承了Qwidget并且這個(gè)MyWidget還帶有Q_OBJECT宏:
QObject *obj = new MyWidget;
這個(gè)obj變量其實(shí)是QObject*類(lèi)型,實(shí)際上他指向的是MyWidget對(duì)象,可以能夠適當(dāng)?shù)膶?duì)他進(jìn)行轉(zhuǎn)化:
從QObject轉(zhuǎn)化為QWidget是可以成功的,因?yàn)檫@個(gè)對(duì)象實(shí)際上是MyWidget,并且這個(gè)MyWidget是QWidget的子類(lèi)。因?yàn)檫@個(gè)obj對(duì)象實(shí)際上指向的是MyWidget,所以可以把他轉(zhuǎn)變?yōu)镸yWidget*類(lèi)型:
轉(zhuǎn)化成MyWidget是能夠成功的,因?yàn)閝object_cast()能夠使得Qt創(chuàng)建的類(lèi)型與自定義類(lèi)型無(wú)差異。
轉(zhuǎn)化為QLabel是失敗的。這個(gè)指針會(huì)被設(shè)置為0。這使得在運(yùn)行的時(shí)候用不同的方式處理不同的類(lèi)型的對(duì)象成為可能。如下所示:
使用qobject_cast()的對(duì)象要繼承QObject但不需要Q_OBJECT宏以及不需要meta-object代碼,當(dāng)代有Q_OBJECT這個(gè)宏的時(shí)候信號(hào)與槽就不能使用,并且其他與這個(gè)宏有關(guān)的特性也不能用。從元對(duì)象系統(tǒng)這個(gè)角度上來(lái)看,沒(méi)有meta代碼的QObject的子類(lèi)與最原始的meta-object代碼最為相識(shí)。舉個(gè)栗子,QMetaObject::className()不會(huì)準(zhǔn)確的返回他自己類(lèi)的名字,而是會(huì)返回他父類(lèi)或者爺爺類(lèi)或者太爺爺?shù)鹊鹊鹊拿帧?br /> 所以,官方強(qiáng)烈推薦所有的QObject子類(lèi)都使用Q_OBJECT宏不管他是否使用了信號(hào)與槽,以為其他的一些屬性。
?
博主栗子
關(guān)于QMetaObject::className()的栗子
對(duì)比有Q_OBJECT宏與無(wú)Q_OBJECT宏的差異
源碼如下:
metaobjectdemo.h
#ifndef METAOBJECTDEMO_H #define METAOBJECTDEMO_H#include <QObject>class MetaObjectDemo : public QObject {Q_OBJECT public:MetaObjectDemo(QObject *parent = 0); };class WithoutQ_OBJECT:public QObject{ public:WithoutQ_OBJECT(QObject *parent=0); };class ParticularClass:public MetaObjectDemo{ public:ParticularClass(QObject *parent=0); };#endif // METAOBJECTDEMO_Hmain.cpp
#include "metaobjectdemo.h" #include <QApplication> #include <QDebug> #include <QMetaObject>int main(int argc, char *argv[]) {QApplication a(argc, argv);MetaObjectDemo *metaObject=new MetaObjectDemo;WithoutQ_OBJECT *withQ_OBJECT=new WithoutQ_OBJECT;ParticularClass *particularClass=new ParticularClass;qDebug()<<"MetaObjectDemo class in metaObject:"<<metaObject->metaObject()->className();qDebug()<<"WithoutQ_OBJECT class in metaObject:"<<withQ_OBJECT->metaObject()->className();qDebug()<<"ParticularClass class in metaObject:"<<particularClass->metaObject()->className();return a.exec(); }metaobjectdemo.cpp
#include "metaobjectdemo.h"MetaObjectDemo::MetaObjectDemo(QObject *parent): QObject(parent) {}WithoutQ_OBJECT::WithoutQ_OBJECT(QObject *parent): QObject(parent) {}ParticularClass::ParticularClass(QObject *parent): MetaObjectDemo(parent) {}運(yùn)行截圖如下:
從這里來(lái)看,并沒(méi)有讓大家失望,可以不通過(guò)RTTI就能實(shí)現(xiàn)對(duì)象的識(shí)別,是不是很有用呢!!!!
?
?
總結(jié)
以上是生活随笔為你收集整理的Qt文档阅读笔记-The Meta-Object System解析及实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++ opengl 复合运动
- 下一篇: STL学习笔记-set的基本原理以及插入