注:此文是从我的QQ空间里移出来的,因为觉的用那么多空间,blog了太累了,它发表于 2009年12月31日 13:58
-----------------------------------------------------------------------------------------------------------------------------------------------------
本文转自:我朋友的QQ空间,如需要转载,请注明本地址
元对象系统的整体结构分析(续二)
又是全日制的一天,早上七点到晚上的9点,不过下午睡了两个小时,感觉还是挺精神的呢。今天对我们的程序有了些新的想法,程序又要重写了,不过已经习惯了,也就无所谓了。晚上继续进行我的源代码分析,看看今天会有什么新的收获?现在就开始我的Qt之旅:
回忆一下,昨天在分析QMetaObject类,所以我们还从这里入手:
在Qt的文档当中,提到了QMetaObject类是在每个QObject子类创建时创建,保存该类全部的元对象相关信息,通过metaObject函数获得QMetaObject类的对象指针。因此,我们需要进入metaObject()函数看个究竟:
首先在qobject.h的头文件中就看到了这样的前向声明:
class QEvent;
class QTimerEvent;
class QChildEvent;
struct QMetaObject;
class QVariant;
class QObjectPrivate;
class QObject;
class QThread;
class QWidget;
接下来,去找metaObject()函数了。找了半天才发现,都已经忘记了,该方法是通过Q_OJBECT宏实现的定义:
#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:
发现该函数的实现是由元对象编译器实现的:
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
这里引用了QObject::d_ptr变量,去看看是什么东西。
QScopedPointer<QObjectData> d_ptr;
QScopedPointer类是Qt4.6最新的一个类,用于负责删除new以后,需要在指针作用域完成时,将new出来的对象进行删除。
QObjectData类中包含了metaObject类的指针。我现在需要找到的是,该变量在什么地方被初始化的。
再次来到QObject的构造函数:
QObject::QObject(QObject *parent)
: d_ptr(new QObjectPrivate)
{
Q_D(QObject);
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
d->threadData->ref();
QT_TRY {
if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
parent = 0;
setParent(parent);
} QT_CATCH(...) {
d->threadData->deref();
QT_RETHROW;
}
qt_addObject(this);
}
可以看到d_ptr指向了QObjectPrivate对象,去看看:
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
该类继承自QObjectData类。
// QObjectData initialization
q_ptr = 0;
parent = 0; // no parent yet. It is set by setParent()
isWidget = false; // assume not a widget object
pendTimer = false; // no timers yet
blockSig = false; // not blocking signals
wasDeleted = false; // double-delete catcher
sendChildEvents = true; // if we should send ChildInsert and ChildRemove events to parent
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i)
connectedSignals[i] = 0;
inEventHandler = false;
inThreadChangeEvent = false;
deleteWatch = 0;
metaObject = 0;
hasGuards = false;
这里将metaObject赋值为空,还需要继续找……到现在还是没有找到关于该变量的赋值操作,只能暂时放下了,看来QObject类真的非常复杂,需要慢慢思考,理顺思路。
明天继续了……