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相关推荐
- 介绍 Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
这两个宏在Qt的源码中随处可见,重要性不言而喻.因为 QObject 本身比较复杂,这两个宏和一个复杂的东西搅和到一块,还真是不好理解.不过幸好,这个两个宏和QObject 没有必然的联系.故接下来, ...
- 6、Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- Qt维基文档翻译:D-指针,D-Pointer
内容目录 什么是d-指针 二进制兼容性 - 是什么? 什么因素会打破二进制兼容性? 为什么它会崩溃? 永远不要改变一个已经导出的C++类的尺寸 d-指针 d-指针所带来的其它好处 q-指针 继承d-指 ...
- 【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 ...
- Qt中的d指针和q指针
概述 如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的. 如果一个程序需要重新编译来运行一个新版本的库,但是不需要对程序的源代码 ...
- Q_D指针和Q_Q指针
作用: 信息隐藏:把类头文件中的私有数据成员和方法隐藏起来,只暴露用户需要的接口 二进制兼容:如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库 ...
- 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. ...
- 0.QObject的数据存储
一.QObject概述 QObject类是QT的核心,大部分QT类都是从这个类直接或者间接继承而来.包含QT的信号槽机制和事件机制 QObject通过对象树将对象组织起来,当使用QObject创建一个 ...
- 解读 Q_D, Q_Q 指针
见 qglog.h文件定义: #define Q_D(Class) Class##Private * const d = d_func() #define Q_Q(Class) Class * ...
最新文章
- server 2008 中活动目录的迁移
- java 获取计算机内存
- JAVA——关闭ServerSocket
- java 分页查询_JavaWeb之分页查询
- mysql 索引扩展
- python 的文件类操作
- 蓝桥杯 历届试题 剪格子(dfs搜索)
- 关于SQL中Between语句查询日期的问题
- 第三届 Apache Flink 极客挑战赛暨 AAIG CUP:Cluster Serving 概况
- Ubuntu下安装Flask虚拟环境及使用
- 【计算机视觉】【并行计算与CUDA开发】GPU硬编码
- 零基础CSS入门教程(26)–CSS按钮实例
- 关于protues仿真中的OLED显示模块的使用
- java程序用maven打包的命令
- AutoUpdater 实现一个简易的自动升级工具
- 安卓模拟PC浏览器发送http请求
- 【Axure教程】鼠标右键显示菜单
- MySQL基本概念和正确发音(表、列、行、注解等讲解)
- ERROR: cannot launch node of type [turtlesim /turtlesim_node]: turtlesim
- 穆利堂[推荐]WxCSM客户服务整体解决方案-河南郑州房地产客户服务管理系统软件-穆穆-movno1
热门文章
- 前端——js 天猫商品图放大镜效果、鼠标移动显示放大效果、(查看图片细节)
- 创新杯论文——面向中文专利信息的关系数据库检索优化策略研究及应用
- 上海交通大学计算机学院拟录取,2021年上海交通大学第0001号本科新生录取通知书今发出,首批收到的是强基计划新生...
- uni-app入门------便签APP的项目记录
- R语言对布丰投针(蒲丰投针)实验进行模拟和动态可视化生成GIF动画
- 【UML】UML中的各种图
- 手机的基站与基站之间是如何通讯的?
- Redis高级应用(二)--哨兵模式
- 响应式布局(Responsive Layout)/流式布局(Fluid Layout)/自适应布局(Adaptive)
- 概率统计18——再看大数定律