原因:只要Qt内部增加/删除/修改/改变顺序/改变类型任何一个私有成员,所有使用Qt的程序都必须重新编译,否则会出现未定义行为(内存错位、崩溃等)。
d指针指向的私有数据专门有相应头文件 qwidget_p.h(其中p:private)来定义。
1、类定义d指针
cpp
class Q_CORE_EXPORT QObject
{
Q_OBJECT
Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
Q_DECLARE_PRIVATE(QObject)
...
QScopedPointer<QObjectData> d_ptr;
...
}
1.1、Q_DECLARE_PRIVATE定义
cpp
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
inline const Class##Private* d_func() const \
{ Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
friend class Class##Private;
Q_DECLARE_PRIVATE(MyWidget)展开
cpp
inline MyWidgetPrivate* d_func()
{
Q_CAST_IGNORE_ALIGN(return reinterpret_cast<MyWidgetPrivate *>(qGetPtrHelper(d_ptr));)
}
inline const MyWidgetPrivate* d_func() const
{
Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const MyWidgetPrivate *>(qGetPtrHelper(d_ptr));)
}
friend class MyWidgetPrivate;
1.2、 QObjectData定义
cpp
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 deleteLaterCalled : 1;
uint unused : 24;
int postedEvents;
QDynamicMetaObjectData *metaObject;
QMetaObject *dynamicMetaObject() const;
};
class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate qwidget_p.h(其中p:private,经常会变化的部分提取出来)
class Q_CORE_EXPORT QObjectPrivate : public QObjectData qobject_p.h(其中p:private,经常会变化的部分提取出来)
2、私有类定义q指针 (继承了 QObjectData中定义了 QObject *q_ptr)
cpp
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
public:
...
Q_DECLARE_PUBLIC定义
cpp
#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \
friend class Class;
Q_DECLARE_PUBLIC(QObject)宏展开
cpp
inline QObject* q_func() { return static_cast<QObject *>(q_ptr); } \
inline const QObject* q_func() const { return static_cast<const QObject *>(q_ptr); } \
friend class QObject;