QObject继承出来的类的成员变量也都相应的要在 QObjectData这个 class继承出 来。而纯虚的析构函数
又决定了两件事:
* 这个 class不能直接被实例化。换句话说就是,如果你写了这么一行代码,new QObjectData, 这行代
码一定会出错,compile的时候是无法过关的。
* 当 delete 这个指针变量的时候,这个指针变量是指向的任意从 QObjectData继承出来的对象的时候,
这个对象都能被正确 delete,而不会产生错误,诸如,内存泄漏之类的。
我们再来看看这个宏做了什么,Q_DECLARE_PRIVATE(QObject)
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } \
inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private
*>(d_ptr); } \
friend class Class##Private;
这个宏主要是定义了两个重载的函数,d_func(),作用就是把在 QObject这个 class中定义的数据成员变
量 d_ptr安全的转换成为每一个具 体的 class的数据成员类型指针。我们看一下在 QObject这个 class中,
这个宏展开之后的情况,就一幕了然了。
Q_DECLARE_PRIVATE(QObject) 展开后,就是下面的代码:
inline QObjectPrivate* d_func() { return reinterpret_cast<QObjectPrivate *>(d_ptr); }
inline const QObjectPrivate* d_func() const
{ return reinterpret_cast<const QObjectPrivate *>;(d_ptr); } \
friend class QObjectPrivate;
宏展开之后,新的问题又来了,这个 QObjectPrivate是从哪里来的?在 QObject这个 class中,为什么不
直接使用 QObjectData来数据成员变量的类型?
还记得我们刚才说过吗,QObjectData这个 class的析构函数的纯虚函数,这就说明这个 class是不能实
例化的,所以,QObject这个 class的成员变量的实际类型,这是从 QObjectData继承出来的,它就是
QObjectPrivate !
这个 class 中保存了许多非常重要而且有趣的东西,其中包括 QT 最核心的 signal 和 slot 的数据,属
性数据,等等,我们将会在后面详细讲解,现在我们来看一下它的定义:
下面就是这个 class的定义:
class QObjectPrivate : public QObjectData
{
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.