本文介绍的是qt 内省机制,关于内省,新手的原因,我们一块学习,所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力, 比如如果该语具有运行期间检查对象型别的能力,那么我们称它是型别内省(type intropection)的,型别内省可以用来实施多态。
c++的内省比较有限,它仅支持上面所说的型别内省,c++的型别内省是通过运行时类型识别(rtti)(run-time type information)中的typeid 以及 dynamic_case关键字来实现的,举例说明:
// rabbit 派生于 animal, jump为虚函数
if ( rabbit *p=dynamic_case(obj))
{
p->jump();
}
//我们还可以通过typeid萃取到对象的型别信息,比如对象的名称
std::cout<
//每个对象可以通过qobject::inherits方法来查询是否对前对象类派生于量一个类
boolisherited=obj.inherits(qobject); // returns true
isherited=obj.inherits(qwideget); // returns true
让我们再来一下qobject::inherits方法的底层实现:
inline bool inherits(const char *classname) const
{ return const_cast(this)->qt_metacast(classname) != 0; }
原来,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()t和inherits()都是借助元对象系统来实现其功能的,iswidgettype()是qobject本身的标志位得以实现。
更多自省方法定义在qmetaobject,以下是qmetaobject声明的源代码:
struct q_core_export qmetaobject
{
const char *classname() const;
const qmetaobject *superclass() const;
qobject *cast(qobject *obj) const;
....
int methodoffset() const;
int enumeratoroffset() const;
int propertyoffset() const;
int classinfooffset() const;
int constructorcount() const;
int methodcount() const;
int enumeratorcount() const;
int propertycount() const;
int classinfocount() const;
int indexofconstructor(const char *constructor) const;
int indexofmethod(const char *method) const;
int indexofsignal(const char *signal) const;
int indexofslot(const char *slot) const;
int indexofenumerator(const char *name) const;
int indexofproperty(const char *name) const;
int indexofclassinfo(const char *name) const;
...
}
上述方法主要是实现对元对象表的访问及其操作,对元对象表(由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 **); \
总结:
1、qt是通过qobject、qmetaobject类实现其内省机制,
2、qobject暴露给用户的共有自省方法有objectname(), inherits(), iswidgettype()等
3、大多数自省方法是qobject派发给qmetaobject实现 (e.g. qmetaobject::classname,),元对象模型编译器moc负责自省方法的实现
OPPO Reno3 Pro细节透露 在轻薄机身的基础上实现了高性能
用更舒适的佩戴享受音乐感受开放式索尼耳机LinkBuds
扩大40年期电源电压范围,从<300uA到3A无电阻电流检测解决方案
西门子TCP开放式通信协议简单介绍
如何提高5G通讯电源可靠性
解析c++语言的Qt内省机制
AMD成台积电第一大7nm客户 成功超越苹果和海思
荣耀20 Pro曝光没有采用全面屏或许会采用升降式摄像头设计
移动卫星服务为欧洲卫星通讯领域翻开新篇章
FPGA设计中 Verilog HDL实现基本的图像滤波处理仿真
超级计算机性能百亿亿次时代开启 SK海力士HBM3为超算加速
IM7587阻抗分析仪介绍
介绍一款基于PoE的互联照明设计
【疫情防控】新冠肺炎疫情常态化管理中的体温检测方法
iphone8什么时候上市?iphone8或存在缺陷?iphone8重新设计发布延期
四川油库反无人机主动防御系统解决库区空域安全防控薄弱问题
电荷放大器频率特性_电荷放大器的特点
红魔3S将搭载90Hz刷新率屏幕 并暗示将支持风冷散热
限制操作过电压的防范措施
技术方案丨5G教育平板/学习机定制化生产方案