Qt元编译器系统(一)

Qt的元对象编译器(MOC)

  • 首先必须知道Qt的信号槽系统是通过元对象编译器moc(Meta-Object Compiler)实现的;
  • 听着很懵,但仔细回想一下,再开发工程中是不是都能看到一堆moc_XXXX.cpp的文件,这其实就是Qt元编译器产生的转义中间文件;
  • 在Qt工程中,如果类声明中包含Q_OBJECT宏定义,则会生成另外一个moc_XXXX.cpp的C++文件;
emit

跳转到emit的定义,会发现本身就是一个空的宏,也就说,发送信号本质上是执行了一个函数。在这里插入图片描述

Q_OBJECT
  • 跳转到Q_OBJECT的定义,有一个关键的静态成员变量staticMetaObject和私有方法qt_static_metacall;
  • 在这里插入图片描述
moc文件
QT_INIT_METAOBJECT const QMetaObject XXX::staticMetaObject = { {
    QMetaObject::SuperData::link<QWidget::staticMetaObject>(),
    qt_meta_stringdata_XXX.data,
    qt_meta_data_XXX,
    qt_static_metacall,
    nullptr,
    nullptr
} };

staticMetaObject 这是用来存类的信号、槽、属性等元信息,并且把qt_static_metacall作为函数指针存储起来。由于是静态元对象,所有该类的实例都会共享同一个,不要重复占用内存,减少了开销。

  • qt_static_metacall 用与执行有关的绑定的槽函数或者相关的信号转发

  • qt_meta_data_XXX 用于存储元对象信息,包括信号和槽机制、参数类型信息和一些动态属性在这里插入图片描述

  • qt_meta_stringdata_XXX.data就是存入了访问stringdata0子字符串的指针变量及长度
    在这里插入图片描述
    static const qt_meta_stringdata_XXXX_t qt_meta_stringdata_XXXX:用于存储函数列表及参数信息,内部通过将所有函数拼接成字符串,通过QT_MOC_LITERAL进行字符串的划分;

三个公有方法metaObject、qt_metacast、qt_metacall
  • metaObject 用于获取函数的元对象(基本上无需理解,元对象具体是什么,可以看一下QMetaObject的声明)
  • qt_metacast 可以在运行时根据字符串名,将当前对象转为相应的基类对象指针,如果转换不成功就是 nullptr
  • qt_metacall 这个是调用函数的回调,_c 是元调用方式(QMetaObject::Call ),_id 是属性的绝对序号(Qt对象树顶层QObject到当前方法的索引),_a 是对应需要的需要的参数指针
结论

至此,可能大概对Qt的元编译器有了一个大概了解,也大概明白了Qt信号槽的底层实现(函数回调,只是开发人员几乎无法感知),如果有看不懂的,一定要先了解Qt元对象(QMetaObject)的基础知识。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值