在Qt中提供了c++的扩展,提供了一种元对象系统的机制,(meta-object-system)的机制。其中包含了信号与槽的内部机制,能够访问到QObject子类的元对象信息的功能。

Q_OBJECT 宏声明了在每一个QObject子类中必须首选的内省函数:metaObject(),tr(),qt_metacall()以及其他一些函数

Qt的moc工具生成了用于Q_OBJECT声明的所有函数和所有信号的实现

同时也提供了connect()和disconnect()这样的内省函数

Qt 不使用标准的C++语言,而是进行了一定程度的扩展,增加了一些新的关键字(例如 signals、slots、emit 等),并实现了反射(内省)机制。

我们知道,C++的对象内存模型非常干净,只有成员变量和成员函数,没有保留额外的类型信息,这使得C++非常高效。所谓类型信息,就是对象所属的类、所包含的成员函数和成员变量(以及它们的修饰符)、所在的继承关系等。类型信息用来描述一个对象的各种属性。

虽然C++提供了RTTI机制,但非常简陋,对象被创建后仅能获得类的名字,这使得RTTI不堪重用,如同鸡肋。像Java、C#等面向对象的语言,可以通过对象完整还原出类的信息,例如类的名字、父类、类所包含的成员变量和成员函数以及它们的修饰符等。这被称作反射机制或内省机制,也就是说对象可以认知自己。

反射机制无疑会增加额外的存储空间,在效率上有所牺牲,而且在普通程序中没有用武之地,为了保持几乎与C同等的效率,C++不提供反射机制也有一定的道理。

但对于大型框架或类库来说,反射机制有时很有必要,它会增加程序的灵活性和动态性,例如动态加载类、解耦等。最明显的一个例子是编译器的智能提示,当输入完对象的名称,再输入.或->,就会提示该对象拥有的变量和函数,这是反射机制的典型应用。

如今,C++的反射机制在 Qt、Boost 等框架中的实现已经非常成熟。

moc

Qt 在将源代码交给标准C++编译器之前,例如GCC、VS等,需要提前将这些扩展的语法去除掉。完成这一操作的就是 moc。

moc 全称是"Meta-Object Compiler",也就是”元对象编译器“。moc 就是一个源代码分析程序,它会读取C++源文件,如果发现在一个头文件中包含了宏 Q_OBJECT,则会生成另外一个C++源文件。这个源文件中包含了 Q_OBJECT 宏的实现代码。这个新文件的名字将由源文件名加上moc_前缀构成,读者可以在 Debug 或 Release 目录中找到。

新文件并不会替换旧文件,而是与旧文件一起进入编译系统,最终被链接到二进制代码中去。

可以发现,moc 的执行在C++预处理器之前,因为预处理器执行之后会进行宏替换,Q_OBJECT 就不存在了。

元对象系统

Qt中的元对象系统是用来处理对象间通讯的信号/槽机制、运行时的类型信息和 动态属性系统。

它基于下列三类:

  1. QObject类;为所有需要利用原对象系统的对象提供了一个基类。
  2. 类声明中的私有段中的Q_OBJECT宏;通常可以声明在类的私有段中,让该类可以使用元对象的特性,比如动态属性,信号和槽。
  3. 元对象编译器(moc)。元对象编译器(moc)为每个QObject子对象自动生成必要的代码来实现元对象特性。

moc读取C++源文件。如果它发现其中包 含一个或多个类的声明中含有Q_OBJECT宏,它就会给含有Q_OBJECT宏的类生成另一个 含有元对象代码的C++源文件。这个生成的源文件可以被类的源文件包含(#include) 到或者和这个类的实现一起编译和连接。

除了提供对象间通讯的信号和槽机制之 外(介绍这个系统的主要原因),QObject中的元对象代码还提供以下特征:

虽然你使用QObject作为一个基类而不使用Q_OBJECT宏和元对象代码是可以的, 但是如果Q_OBJECT宏没有被使用,那么这里的信号和槽以及其它特征描述都不会被 提供。根据元对象系统的观点,一个没有元代码的QObject的子类和它含有元对象代 码的最近的祖先相同。举例来说就是,className()将不会返回你的类的实际名称, 返回的是它的这个祖先的名称。我们强烈建议QObject 的所有子类使用Q_OBJECT宏,而不管它们是否实际使用了信号、槽和属性

http://blog.csdn.net/tingsking18/article/details/4800828

Qt元对象系统简介的更多相关文章

  1. Qt 元对象系统(Meta-Object System)(不管是否使用信号槽,都推荐使用)

    Qt 元对象系统(Meta-Object System) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的对象提供了一个基类. 宏:Q_OBJECT,通常可以声明在类 ...

  2. Qt 元对象系统(Meta-Object System)

    (转自:http://blog.csdn.net/aladdina/article/details/5496891) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的 ...

  3. 解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good

    概述查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别. 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起. Q_INVOKABLE与QMe ...

  4. 解析Qt元对象系统(四) 属性系统(确实比较方便)

    官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...

  5. qt 元对象系统

    元对象系统 Qt中的元对象系统是用来处理对象间通讯的信号/槽机制.运行时的类型信息和 动态属性系统. 它基于下列三类: QObject类: 类声明中的私有段中的Q_OBJECT宏: 元对象编译器(mo ...

  6. Qt笔记——元对象系统

    Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...

  7. 深入了解Qt(二)之元对象系统(Meta-Object System)

    深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...

  8. QtCore是Qt的精髓(包括五大模块:元对象系统,属性系统,对象模型,对象树,信号槽)

    作者:小豆君的干货铺链接:https://www.zhihu.com/question/27040542/answer/218384474来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  9. Qt对象模型之二:对象树与元对象系统

    一.对象树的概念 Qt中使用对象树(object tree)来组织和管理所有的QObject类及其子类的对象.当创建一个QObject时,如果使用了其他的对象作为其父对象(parent),那么这个 Q ...

随机推荐

  1. sencha touch NavigationView 嵌套 TabPanel 的问题

    在st2.1之中,在NavigationView视图之中在嵌套一个TabPanel会有以下问题 下面我们监控TabPanel的activate事件和activeitemchange事件 会发现当首页加 ...

  2. SecureCRT无法使用root账户远程连接ubuntu

    ========1.问题============ SecureCRT无法使用root账户远程连接ubuntu 用其他账户连接,正常 用root账户连接,不能连接 =========2.原因====== ...

  3. Nginx之让用户通过用户名密码认证访问web站点

    有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问. 那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那 ...

  4. iOS 通过(lame)将录制音频转换成Mp3

    版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处,保留原帖地址及作者署名. Url:http://blog.csdn.net/ysy441088327/article/detail ...

  5. Windows Server 2008 R2之三管理活动目录数据库

    活动目录数据库包括数据库文件NTDS.dit和日志文件.考虑到最佳性能,在生产环境推荐将日志文件和数据库文件在单独的硬盘驱动器中或RAID中,同时要根据网络的规模,保证磁盘上有充足的剩余空间.由于活动 ...

  6. 利用 bugly 分析应用崩溃

    Bugly-Crash监控能让我们及时的掌控应用的Crash,并快速修复.这种情况就在于我们把应用发布出去了,但是用户那边有着各种各样我们想象不到的系统崩溃,我们无法通过简单的控制台捕获错误信息和崩溃 ...

  7. wireshark抓取OMCI报文

    1.安装文件: 1.1 BinDecHex.lua 1.2 omci.lua 2.如上两个文件copy至wireshark安装目录,如C:\Program Files (x86)\Wireshark ...

  8. php---截取描述方法

    参考: https://www.cnblogs.com/xsphehe/p/5682004.html 示例: /** * 参数说明 * $string 欲截取的字符串 * $sublen 截取的长度 ...

  9. 爬取博主的所有文章并保存为PDF文件

    继续改进上一个项目,上次我们爬取了所有文章,但是保存为TXT文件,查看不方便,而且还无法保存文章中的代码和图片. 所以这次保存为PDF文件,方便查看. 需要的工具: 1.wkhtmltopdf安装包, ...

  10. TFS二次开发09——查看文件历史(QueryHistory)

    这篇文章给大家展示怎样获取一个文件的历史版本,内容很简单,直接上代码了. string tpcURL = "http://127.0.0.1:8080/"; TfsTeamProj ...