Qt MetaObject 详解之一:简单介绍

这个系列的几篇文章通过阅读Qt帮助文档和相关的源代码来学习研究Qt meta-object所提供的功能,及其实现的方式。

Qt meta-object系统基于三个方面:

 1、QObject提供一个基类,方便派生类使用meta-object系统的功能;

 2、Q_OBJECT宏,在类的声明体内激活meta-object功能,比如动态属性、信号、槽;

 3、Meta Object编译器(MOC),为每个QObject派生类生成代码,以支持meta-object功能。

QObject定义了从一个QObject对象访问meta-object功能的接口,Q_OBJECT宏用来告诉编译器该类需要激活meta- object功能,编译器在扫描一个源文件时,如果发现类的声明中有这个宏,就会生成一些代码来为支持meta-object功能——主要是生成该类对应 MetaObject类以及对QObject的函数override。

QObject和QMetaObject:

顾名思义,QMetaObject包含了QObject的所谓的元数据,也就是QObject信息的一些描述信息:除了类型信息外,还包含QT中特 有的signal&slot信息。

 QObject::metaObject ()方法返回一个QObject对象对应的metaobject对象,注意这个方法是virtual方法。如上文所说,如果一个类的声明中包含了 Q_OBJECT宏,编译器会生成代码来实现这个类对应的QMetaObject类,并重载QObject::metaObject()方法来返回这个 QMetaObject类的实例引用。这样当通过QObject类型的引用调用metaObejct方法时,返回的是这个引用的所指的真实对象的 metaobject。

如果一个类从QObject派生,确没有声明Q_OBJECT宏,那么这个类的metaobject对象不会被生成,这样这个类所声明的 signal slot都不能使用,而这个类实例调用metaObject()返回的就是其父类的metaobject对象,这样导致的后果就是你从这个类实例获得的元 数据其实都是父类的数据,这显然给你的代码埋下隐患。因此如果一个类从QOBject派生,它都应该声明Q_OBJECT宏,不管这个类有没有定义 signal&slot和Property。

这样每个QObject类都有一个对应的QMetaObject类,形成一个平行的类型层次。

QMetaObject提供的信息:

下面通过QMetaObject的接口来解读QMetaObject提供的信息:

1、基本信息

     const char * className () const;

     const QMetaObject * superClass () const

2、classinfo: 提供额外的类信息。其实就是一些名值对。 用户可以在类的声明中以Q_CLASSINFO(name, value)方式添加。

      int classInfoCount () const
      int classInfoOffset () const

      QMetaClassInfo classInfo ( int index ) const

      int indexOfClassInfo ( const char * name ) const

3、contructor:提供该类的构造方法信息

     QMetaMethod constructor ( int index ) const
     int constructorCount () const

     int indexOfConstructor ( const char * constructor ) const

4、enum:描述该类声明体中所包含的枚举类型信息

    QMetaEnum enumerator ( int index ) const
    int enumeratorCount () const
    int enumeratorOffset () const

    int indexOfEnumerator ( const char * name ) const

5、method:描述类中所包含方法信息:包括property,signal,slot等,包括祖先类,如何组织暂时不确定。

    QMetaMethod method ( int index ) const
    int methodCount () const
    int methodOffset () const

    int indexOfMethod ( const char * method ) const
    int indexOfSignal ( const char * signal ) const
    int indexOfSlot ( const char * slot ) const

6、property:类型的属性信息

     QMetaProperty property ( int index ) const
     int propertyCount () const
     int propertyOffset () const

     int indexOfProperty ( const char * name ) const

     QMetaProperty userProperty () const  //返回类中设置了USER flag的属性,(难道只能有一个这样的属性?)

注意:对于类里面定义的函数,构造函数,枚举,只有加上一些宏才表示你希望为方法提供meta信息。比如 Q_ENUMS用来注册宏,

Q_INVACABLE用来注册方法(包括构造函数)。Qt这么设计的原因应该是避免meta信息的臃肿。

你可能感兴趣的:(Qt)