在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. python中的list和array的不同之处

    原文地址:  http://blog.csdn.net/liyaohhh/article/details/51055147#reply python中的list是python的内置数据类型,list中 ...

  2. UINavigationItem 设置UIBarButtonItem

    转:http://hi.baidu.com/ivan_xu/item/237bb1ad77eff9b028ce9d7c 有A.B两个ViewController,假如A push B: UINavig ...

  3. Bat脚本实现监控进程功能

    脚本不间断监控notepad.exe进程是否执行,若停止,则自动重启该进程,程序如下: @echo off set _task = notepad.exe set _svr = c:\windows\ ...

  4. LeetCode 22 Generate Parentheses(找到所有匹配的括号组合)

    题目链接 : https://leetcode.com/problems/generate-parentheses/?tab=Description   给一个整数n,找到所有合法的 () pairs ...

  5. LeetCode 10 Regular Expression Matching(字符串匹配)

    题目链接 https://leetcode.com/problems/regular-expression-matching/?tab=Description   '.' Matches any si ...

  6. soanr - 企业用户角色管理

    首先sonar支持群组 即 支持企业角色权限管理,其次sonar支持单项目用户权限管理 即 外包,客户,外编人员用户权限管理. (视图内可看到源码) 按照 管路员.产品/项目管理.产品/项目开发.外包 ...

  7. iOS开发 纯代码创建UICollectionView

    转:http://jingyan.baidu.com/article/eb9f7b6d8a81a5869364e8a6.html iOS开发 纯代码创建UICollectionView 习惯了使用xi ...

  8. AES加密工具类(对称加密算法)

    import java.nio.charset.Charset; import java.security.Key; import javax.crypto.Cipher;import javax.c ...

  9. iOS - 开源框架、项目和学习资料汇总(其他篇)

    数据库 1. FMDB – sqlite的工具, 多线程FMDatabaseQueue实例,FMDB数据库的使用演示和封装工具类.GXDatabaseUtils – 在FMDB基础上的工具.2. re ...

  10. spring c3po 连接mysql,sqlserver

    1  连接mysql (1) http://wenku.it168.com/d_000096351.shtml 2  连接sqlserver (1)http://blog.csdn.net/vinep ...