Qt的q指针和d指针笔记

原因:只要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;
相关推荐
Hello.Reader1 天前
从零开始安装 Qt完整新手教程(1)
开发语言·qt
娇娇yyyyyy1 天前
QT编程(19) : Qt 实现自定义delegate
开发语言·数据库·qt
不想看见4041 天前
QAbstractItemModel 自定义实现--Qt 模型 / 视图(MVC)
开发语言·qt·mvc
不想看见4041 天前
Qt 事件循环与事件过滤器讲解【详细】
开发语言·数据库·qt
FL16238631291 天前
基于yolov8+pyqt5实现的水尺图像识别与水深计算系统
开发语言·qt·yolo
sycmancia1 天前
QT——GUI程序原理分析、Hello QT、调试的基本方法
开发语言·qt
问水っ1 天前
Qt Creator快速入门 第三版 第6章 事件系统
开发语言·qt
不想看见4041 天前
Qt+FFmpeg 极简播放器示例【音视频方向简单讲解】
qt·ffmpeg·音视频
FuckPatience1 天前
QT 不允许使用不完整的类型
qt
四维碎片1 天前
【Qt】 无边框窗口方案
开发语言·qt