- class Test : public QObject
- {
- Q_OBJECT
- public:
- explicit Test(QObject *parent = 0);
- signals:
- public slots:
- };
- /****************************************************************************
- ** Meta object code from reading C++ file 'test.h'
- **
- ** Created: Thu Jul 22 13:06:45 2010
- ** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
- **
- ** WARNING! All changes made in this file will be lost!
- *****************************************************************************/
- #include "../test.h"
- #if !defined(Q_MOC_OUTPUT_REVISION)
- #error "The header file 'test.h' doesn't include
." - #elif Q_MOC_OUTPUT_REVISION != 62
- #error "This file was generated using the moc from 4.6.3. It"
- #error "cannot be used with the include files from this version of Qt."
- #error "(The moc has changed too much.)"
- #endif
- QT_BEGIN_MOC_NAMESPACE
- static const uint qt_meta_data_Test[] = {
- // content:
- 4, // revision
- 0, // classname
- 0, 0, // classinfo
- 0, 0, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 0, // signalCount
- 0 // eod
- };
- static const char qt_meta_stringdata_Test[] = {
- "Test\0"
- };
- const QMetaObject Test::staticMetaObject = {
- { &QObject::staticMetaObject, qt_meta_stringdata_Test,
- qt_meta_data_Test, 0 }
- };
- #ifdef Q_NO_DATA_RELOCATION
- const QMetaObject &Test::getStaticMetaObject() { return staticMetaObject; }
- #endif //Q_NO_DATA_RELOCATION
- const QMetaObject *Test::metaObject() const
- {
- return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
- }
- void *Test::qt_metacast(const char *_clname)
- {
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_Test))
- return static_cast<void*>(const_cast< Test*>(this));
- return QObject::qt_metacast(_clname);
- }
- int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
- {
- _id = QObject::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- return _id;
- }
- QT_END_MOC_NAMESPACE
- #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 **); \
- private:
首先看一下简单含有的signal, slot代码
编译生成moc_myClass.cpp
其中methods部分,4代表这个对象含有4个signal + slot, 14是基础数字,在moc代码里面也是硬编码,数一下content的个数,刚好是14,这个14其实就是个偏移量,偏移到signal的第一行
signal和slot的flag提供了一些属性,这个会在后面的QObject::connect讲到。
这里需要提出来一点是signal和slot的第一个数值,9, 34, 56, 73这几个,这个马上会讲到先提出来,留个印象
这里前14个数值是对应的QMetaObjectPrivate的值
接下来是
从这个字符串里面,可以看到第一个值为这个类的类名(元对象可以不通过RTTI给出类名的原因就在这里)
在第一个/0后面会给出第一个signal的返回值类型,在这个例子中signalFunc没有返回值,所以没有任何内容,
在第二个/0后面会给出参数名,因为moc读取的是头文件,而我们在头文件中没定义参数名,所以为空
然后就是signal的名字和参数列表类型,这里需要注意的是,即使头文件给出了参数名,在这里也会被忽略掉,只提供类型
再下一个/0后面就是下一个函数的描述了,描述的方式跟前面是一样的。
刚刚提到的9, 34, 56, 73这几个数字,在这里是有用的,这几个数字,刚好是这个字符串对应的函数开头的部分。比如9,那我们在这个字符串中数9个字符,即signalFunc(double)这一段内容。
然后是源对象的数据定义:
这个名为staticMetaObject的对象是由Q_OBJECT引入的
第一个数据为父类名字, moc对于多继承的限制可能也在于此。
moc规定多继承的情况下,moc会假设第一个继承的类为QObject, 并且必须要保证在多继承中,只有唯一一个类是继承自QObject的。这样看上去,多余一个QObject继承的,第二个QObject根本没办法识别出来。
第二个数据就是上面的字符串数据
第三个也是上面的uint*数据。
这个源对象非常关键,后面的内容就靠他了。
这2个方法都是由Q_OBJECT引入的。目的是返回这个类的元对象
还是由Q_OBJECT引入的
当传入的字符串数据是当前这个类的话,就将this指针转换成void指针传给外界: 这个操作相当危险。
如果不是当前类的话,就调用父类的qt_metacast继续查询。
在这里,我的父类是QObject,所以自然就调用QObject::qt_metacase了
在看qt_metacall之前,先看下signal的定义。 额。。事实上signal不需要你自己定义,moc已经帮我们完成这点了。
具体内容如下:
我们看到他将所有的参数都转型成void*指针保存到 void *a的数组中,然后调用了
QMetaObject::activate(this, &staticMetaObject, 0, _a);
看到传入的参数为this, 源对象和参数
这个函数实际上就是触发消息的函数,在这里不过多关注他,有机会再写
最终,int myClass::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
会被调用,用来处理对应的signal的消息
代码如下
这里可以注意下,有返回值和没有返回值的处理方法~
moc所作的这些工作,都是为了元对象能更好的工作而做的准备
以上内容转载自: http://blog.csdn.net/liuysheng/article/details/6822718