1. d指针

QT wiki D_Pointer

  • 作用

    • 隐藏接口具体实现细节

    • 提高程序编译速度

    • 最大程度实现二进制兼容

      • 二进制兼容动态库:动态链接到库的前一个版本的程序继续与库的新版本一起运行而不需要重新编译,则库是二进制兼容的。程序需要重新编译以使用新版本的库运行,但不需要任何进一步的修改,则该库是源代码兼容的。

      • 如何使动态库二进制兼容:就要求每一个结构以及每一个对象的数据模型保持不变。所谓“数据模型保持不变”,就是不能在类中增加、删除数据成员

      • 方法:1.预先分配若干个保留空间,后续添加数据使用保留空间(使用位域:int n:20)

        2.将预分配保留空间类型由常规变量改为对象指针

        也就是让所有的共有类都拥有一个指针,这个指针包含所有数据的私有数据结构。且这个私有的数据结构可在任意版本中修改,从而不影响该类的使用,因为这个指针是私有的,外部调用只能看到一个不变化的共有类,该共有类只拥有一个指针,这个指针就是称为d指针的Q_D指针。

    • Q_DECLARE_PRIVATEQ_D配合使用是为了获取d指针,d指针指向Class##Private私有类

// 第一种
class Q_CORE_EXPORT QObjectData {Q_DISABLE_COPY(QObjectData)
public:QObjectData() = default;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 QWindowuint deleteLaterCalled : 1;uint unused : 24;int postedEvents;QDynamicMetaObjectData *metaObject;QMetaObject *dynamicMetaObject() const;#ifdef QT_DEBUGenum { CheckForParentChildLoopsWarnDepth = 4096 };
#endif
};
//第二种
class Q_CORE_EXPORT QObject
{// Q_DECLARE_PRIVATE作用:定义当前类内联函数d_fun() 并使其指向私有类的实现,同时将私有类声明位-当前类的友元类Q_DECLARE_PRIVATE(QObject)
protected:QScopedPointer<QObjectData> d_ptr;
};QObject::QObject(QObjectPrivate &dd, QObject *parent): d_ptr(&dd)
{Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");// Q_D 作用:Q_D只作用于当前函数作用域,在每个函数的第一行使用,定义了一个QObjectPrivate的常量指针 指向d_func() ,因此通过Q_D 可以访问d指针// d指针需要手动释放,但是QT中使用的是QScopedPointer 无需手动释放Q_D(QObject);d_ptr->q_ptr = this;//...
}
// <------------------ Q_DECLARE_PRIVATE 宏定义解析 ------------------->
#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;//------------------转换后
inline QObjectPrivate* d_func()
{return reinterpret_cast<QObjectPrivate *>(qGetPtrHelper(d_ptr));
}
inline const QObjectPrivate* d_func() const
{Sreturn reinterpret_cast<const QObjectPrivate *>(qGetPtrHelper(d_ptr));
}
friend class QObjectPrivate;// <------------------ Q_D ------------------ >
#define Q_D(Class) Class##Private * const d = d_func()
//------------------转换后
QObjectPrivate* const d = d_func()

2. q指针

  • 作用:配合d指针实现d指针的作用

    • Q_DECLARE_PUBLICQ_Q配合:在C lass##Private中方便获取q指针,q指针指向原class本身
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{Q_DECLARE_PUBLIC(QObject)// ...
};// <------------------ Q_DECLARE_PUBLIC 宏定义解析 ------------------->
#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 作用:定义q_fun() 并使其之前关联类,同时将关联类声明位当前类的友元类
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;// <------------------ Q_Q 宏定义解析 ------------------->
#define Q_Q(Class) Class * const q = q_func()
//------------------转换后
// Q_Q 只作用域当前函数的作用域,在每一个函数中第一行使用
// Q_Q 定义类一个QObjectPrivate常量指针指向q_fun() 因此通过Q_Q可以访问q_指针
QObject * const q = q_func()

Q_D以及Q_Q指针理解相关推荐

  1. 【Qt】通过QtCreator源码学习Qt(十二):Q_D和Q_Q指针(简称“d指针”)详解

    1.Q_D和Q_Q指针(简称"d指针")简介 参考博客: https://www.devbean.net/2016/11/qt-creator-source-study-07/ h ...

  2. 解读 Q_D, Q_Q 指针

    见 qglog.h文件定义: #define Q_D(Class) Class##Private * const d = d_func()     #define Q_Q(Class) Class * ...

  3. Q_D指针和Q_Q指针

    作用: 信息隐藏:把类头文件中的私有数据成员和方法隐藏起来,只暴露用户需要的接口 二进制兼容:如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库 ...

  4. Q_D指针(d指针)和Q_Q指针(q指针)简介

    文章目录 1. Q_D指针 2. Q_Q指针 1. Q_D指针 在class中配合使用 Q_DECLARE_PRIVATE 和 Q_D ,方便获取d指针,d指针指向Class##Private: 2. ...

  5. C++快慢指针理解与应用

    C++快慢指针理解与应用 原理 应用 有序链表中寻找中位数 判断链表是否存在环,如果存在,找到环入口 判断两个单链表是否相交,如果相交找到他们的第一个公共节点 原理 快慢指针中的快慢指的是移动的步长, ...

  6. (*visit)(TElemType e )函数指针理解

    基础知识 函数指针 的本质是一个指针,该指针的地址指向了一个函数,所以它是指向函数的指针.我们知道,函数的定义是存在于代码段,因此,每个函数在代码段中,也有着自己的入口地址,函数指针就是指向代码段中函 ...

  7. C语言指针理解patr1

    今天在看<Head First C语言>中,书中的代码是*lat=*lat+1;我则写成了*lat++:结果是并不能得到lat指针的内容加一.之后发现原来在C语言中*解指针运算符 与++后 ...

  8. c语言指针与数组的深入理解

    引言:本篇再一次写到指针,学过c语言的都知道,指针是初学c语言时候遇到的一个比较难搞的知识点.你尽管可以想的简单,但是其实如果去用的话,没有一个更加深入的理解,那么后续的学习到数据结构就会艰难无比. ...

  9. c语言指针p1p2,C语言指针系列(2):你真的理解指针与内存的关系吗?

    C语言指针可谓是C语言的灵魂,无论是在C语言算法,还是在数据结构,他无处不在.指针,这对于老手如同家常便饭一样的操作,却在萌新面前如同一座万丈高山! 中国的伟人曾经说过: 世上无难事,只怕有心人! C ...

最新文章

  1. 使用Numpy和Scipy处理图像
  2. C++Heap Sort堆排序的实现算法(附完整源码)
  3. 后端开发需要学什么_都2020年了,还在纠结学什么语言?| 后端篇
  4. 马化腾最崇拜的作家吴晓波《历代经济变革得失》读书笔记
  5. PHP 查看系统文件时间戳
  6. SpringMVC(3):DispatcherServlet详解
  7. Think in Java第四版 读书笔记8第14章 类型信息(RTTI与反射)
  8. mysql 2100,MySQL 实现准实时的表级别DML计数
  9. matlab可视化大学物理学_传输矩阵法在大学物理波动光学教学中的应用
  10. 图像变形功能的应用: 在线修整发型
  11. python自定义函数大全-Python自定义函数
  12. js 查看是否为空值
  13. Python学习总结(3)——数字类型
  14. 外挂辅助技术-计算怪物与玩家的距离
  15. LR算法(基础及核心概念)
  16. Java微信授权小程序获取用户昵称头像等基本信息
  17. 【资源下载】分享个嵌入式开发的入门教程(包含视频)
  18. apple开发者文档关于KVC和KVO文档的一些渣翻——这里是原地址
  19. 怎么查看CAD图纸并更改图纸背景颜色?
  20. 阿里/京东入局,多家年营收过亿公司诞生,解析居家护理市场三大趋势

热门文章

  1. 五金与机械行业的WMS系统方案
  2. 如何在 FlowUs、Notion 等笔记软件中进行时间管理?
  3. 跨境电商还有发展前景吗?跨境电商应该怎么运营?
  4. Dan计划:重新定义人生的10000个小时
  5. 港科夜闻|香港科大(广州)熊辉教授获委任为协理副校长(知识转移)
  6. python按指定数量划分图片与对应的xml数据(.png格式为列)
  7. drf实现图片验证码功能
  8. 个人总结之前端技巧-----页面的设计流程
  9. 基于S-FFT的相息图
  10. 你真的懂Linux内核中的阻塞和异步通知机制吗?(花了五天整理,墙裂推荐!)