核心就是
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
d_ptr->q_ptr = this; //互指
}
template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \
inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \
friend class Class##Private;
#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
inline Class##Private* d_func() { return reinterpret_cast(Dptr); } \
inline const Class##Private* d_func() const { return reinterpret_cast(Dptr); } \
friend class Class##Private;
#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() { return static_cast(q_ptr); } \
inline const Class* q_func() const { return static_cast(q_ptr); } \
friend class Class;
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()
看一下两个的定义
class Q_CORE_EXPORT QObject
{
Q_INVOKABLE explicit QObject(QObject *parent=0);
protected:
QObject(QObjectPrivate &dd, QObject *parent = 0);
QScopedPointer<QObjectData> d_ptr;
}
中QObject *q_ptr 的定义
class Q_CORE_EXPORT QObjectData {
public:
virtual ~QObjectData() = 0;
QObject *q_ptr;
QObject *parent;
QObjectList children;
uint isWidget : 1;
uint blockSig : 1;
uint wasDeleted : 1;
uint isDeletingChildren : 1;
uint sendChildEvents : 1;
uint receiveChildEvents : 1;
uint isWindow : 1; //for QWindow
uint unused : 25;
int postedEvents;
QDynamicMetaObjectData *metaObject;
QMetaObject *dynamicMetaObject() const;
};
Q_INVOKABLE explicit QObject(QObject *parent=0);
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();
}
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
Q_D(QObject);
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() { return static_cast(q_ptr); } \
inline const Class* q_func() const { return static_cast(q_ptr); } \
friend class Class;
#define Q_Q(Class) Class * const q = q_func()
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
}
继承自QObjectData,同时通过宏扩展出一个函数q_func ,再通过Q_Q 扩展出一个类类型的指针变量q,以供获取到该私有数据类对应的类型的对象指针。
用QObjectPrivate进行赋值,QObjectPrivate是一个继承QObjectData的类型,通用的定义形式是classNamePrivate,表明是一个继承QObject的类中的私有数据,在整个继承体系中,所有类的私有数据的初始化赋值都到达了Qobject 中定义的QScopedPointer d_ptr,由其进行保存。
QT中私有数据类型的定义一般在XXX_P.h中定义,如qcoreapplication_p.h;但是实现却是和类型一起在同一个.c文件中,例如qcoreapplication.cpp。
然后通过Q_D进行类型的强制转换变为子类所持有的私有数据类型,因为QObjectData也是被各个私有数据类型进行继承和扩展的。
Q_Q的作用就是,将QObejctData中存储的QObject *q_ptr,转换成子类的类型,参数是子类的类型名,经过宏 成为类型,强制转换类型。
d_ptr和q_ptr的就是一对相互持有彼此指针的数据,从q_ptr指向的类型的可以获取到d_ptr的私有数据,通过d_ptr的私有数据类型可以获取到包含d_ptr的类型的类对象指针。
QObject::QObject(QObject *parent)
: d_ptr(new QObjectPrivate)
{
Q_D(QObject);
d_ptr->q_ptr = this;
}
class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWidget)
explicit QWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
}
QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
QT_TRY {
d_func()->init(parent, f);
} QT_CATCH(...) {
QWidgetExceptionCleaner::cleanup(this, d_func());
QT_RETHROW;
}
}
QObject(*new QWidgetPrivate, 0) 使得第一个参数值被赋值到d_ptr,同时QObject 的构造函数中,将d_ptr的中保有的q_ptr赋值为this,即当前类型实例对象的指针。
也可以直接通过传入私有数据类型的引用进行构造,如下。
QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
: QObject(dd, 0), QPaintDevice()
{
Q_D(QWidget);
QT_TRY {
d->init(parent, f);
} QT_CATCH(...) {
QWidgetExceptionCleaner::cleanup(this, d_func());
QT_RETHROW;
}
}