Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC

这两个宏在Qt的源码中随处可见,重要性不言而喻。在 部落格的 Inside Qt Series 系列文章中,他用了3篇文章来讲这个问题。

因为 QObject 本身比较复杂,这两个宏和一个复杂的东西搅和到一块,还真是不好理解。不过幸好,这个两个宏和QObject 没有必然的联系。故接下来,忘记 QObject,看一个普通的C++的类

例子

类 QtServiceController 定义:

class QtServiceController
{Q_DECLARE_PRIVATE(QtServiceController) public:QtServiceController(const QString &name);//省略其他
private:
 QtServiceControllerPrivate *d_ptr;
};

宏定义

宏定义在 QtGlobal(即qglobal.h)头文件中:

#define Q_DECLARE_PRIVATE(Class) \inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \friend class Class##Private;  #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;

这两个宏在这看起来真蛮绕的,因为这个例子太简单了,两个宏的威力发挥不出来。反正核心就是:

  • 在 QtServiceController 中通过 d_func() 可以获得 QtServiceControllerPrivate 的指针 d_ptr

  • 在 QtServiceControllerPrivate 中通过 q_func() 可以获得 QtServiceController 的指针 q_ptr

Q_D 与 Q_Q

这是另两个Qt源码中随处可见的宏,那么它们有什么用呢?

#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func() 

两个宏展开后分别是对 d_func 和 q_func 两个函数的调用,返回值分别赋值给 d 和 q 两个指针变量。

于是:

  • 在 QtServiceController 中的成员函数中,我们只需要添加 Q_D(QtServiceController) 宏,在该函数内就可以直接用 d 来指代 d_ptr

  • 在 QtServiceControllerPrivate 中的成员函数中,我们只需要添加 Q_Q(QtServiceController)宏,在该函数内就可以直接用 q 来指代 q_ptr

d_ptr与q_ptr

绕这么大圈,为什么不直接用 d_ptr 与 q_ptr 呢。在,在我们的例子中,确实可以直接用,而且会更直接更简单。官方这么用了,或许是为了和其他类保持一致吧。

但在其他情况下,这么做显然是有意义的,因为 d_ptr 与 d,q_ptr 与 q 的类型并不一致(比如QObject系列)。这也是为何宏展开后有cast的原因

Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC相关推荐

  1. 介绍 Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC

    这两个宏在Qt的源码中随处可见,重要性不言而喻.因为 QObject 本身比较复杂,这两个宏和一个复杂的东西搅和到一块,还真是不好理解.不过幸好,这个两个宏和QObject 没有必然的联系.故接下来, ...

  2. 6、Qt Meta Object system 学习

    原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...

  3. Qt维基文档翻译:D-指针,D-Pointer

    内容目录 什么是d-指针 二进制兼容性 - 是什么? 什么因素会打破二进制兼容性? 为什么它会崩溃? 永远不要改变一个已经导出的C++类的尺寸 d-指针 d-指针所带来的其它好处 q-指针 继承d-指 ...

  4. 【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 ...

  5. Qt中的d指针和q指针

    概述 如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的. 如果一个程序需要重新编译来运行一个新版本的库,但是不需要对程序的源代码 ...

  6. Q_D指针和Q_Q指针

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

  7. 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. ...

  8. 0.QObject的数据存储

    一.QObject概述 QObject类是QT的核心,大部分QT类都是从这个类直接或者间接继承而来.包含QT的信号槽机制和事件机制 QObject通过对象树将对象组织起来,当使用QObject创建一个 ...

  9. 解读 Q_D, Q_Q 指针

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

最新文章

  1. server 2008 中活动目录的迁移
  2. java 获取计算机内存
  3. JAVA——关闭ServerSocket
  4. java 分页查询_JavaWeb之分页查询
  5. mysql 索引扩展
  6. python 的文件类操作
  7. 蓝桥杯 历届试题 剪格子(dfs搜索)
  8. 关于SQL中Between语句查询日期的问题
  9. 第三届 Apache Flink 极客挑战赛暨 AAIG CUP:Cluster Serving 概况
  10. Ubuntu下安装Flask虚拟环境及使用
  11. 【计算机视觉】【并行计算与CUDA开发】GPU硬编码
  12. 零基础CSS入门教程(26)–CSS按钮实例
  13. 关于protues仿真中的OLED显示模块的使用
  14. java程序用maven打包的命令
  15. AutoUpdater 实现一个简易的自动升级工具
  16. 安卓模拟PC浏览器发送http请求
  17. 【Axure教程】鼠标右键显示菜单
  18. MySQL基本概念和正确发音(表、列、行、注解等讲解)
  19. ERROR: cannot launch node of type [turtlesim /turtlesim_node]: turtlesim
  20. 穆利堂[推荐]WxCSM客户服务整体解决方案-河南郑州房地产客户服务管理系统软件-穆穆-movno1

热门文章

  1. 前端——js 天猫商品图放大镜效果、鼠标移动显示放大效果、(查看图片细节)
  2. 创新杯论文——面向中文专利信息的关系数据库检索优化策略研究及应用
  3. 上海交通大学计算机学院拟录取,2021年上海交通大学第0001号本科新生录取通知书今发出,首批收到的是强基计划新生...
  4. uni-app入门------便签APP的项目记录
  5. R语言对布丰投针(蒲丰投针)实验进行模拟和动态可视化生成GIF动画
  6. 【UML】UML中的各种图
  7. 手机的基站与基站之间是如何通讯的?
  8. Redis高级应用(二)--哨兵模式
  9. 响应式布局(Responsive Layout)/流式布局(Fluid Layout)/自适应布局(Adaptive)
  10. 概率统计18——再看大数定律