Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
|
这两个宏在Qt的源码中随处可见,重要性不言而喻。在 部落格的 Inside Qt Series 系列文章中,他用了3篇文章来讲这个问题。 因为 QObject 本身比较复杂,这两个宏和一个复杂的东西搅和到一块,还真是不好理解。不过幸好,这个两个宏和QObject 没有必然的联系。故接下来,忘记 QObject,看一个普通的C++的类 例子类 QtServiceController 定义: class QtServiceController |
宏定义
宏定义在 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的更多相关文章
- 6、Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- Qt QObject
[1]Qt的QObject 1.测试代码如下: #include<QApplication> #include<QPushButton> #include<QDebug& ...
- 深入了解Qt(一)之QObject
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! QObject这个 class 是 QT 对象模型的核心,关于对象模型可以阅读C++对象模型详解 ...
- Qt源码分析之QObject
原文:http://blog.csdn.net/oowgsoo/article/details/1529284 我感觉oowgsoo兄弟写的分析相当透彻,赞! 1.试验代码: #include < ...
- Qt之四方分割器QuadSplitter
在Qt经常会用到分割器QSplitter,可以对多个控件进行水平或者垂直分割,但有一些特殊的需求无法满足,比如:四方分割...QuadSplitter是qt-apps里面的一个应用,挺不错的,拿来和大 ...
- d指针在Qt上的应用及实现(d指针能实现二进制兼容)
Qt为了使其动态库最大程度上实现二进制兼容,引入了d指针的概念.那么为什么d指针能实现二进制兼容呢?为了回答这个问题,首先弄清楚什么是二进制兼容?所谓二进制兼容动态库,指的是一个在老版本库下运行的程序 ...
- Q_D宏
Qt 源码中有很多Q_Q和Q_D宏,使用这些宏的地方总会看到有q指针和d指针,查了查KDE文档,大体搞清了其中的机理,欧也!Qt的这些私有数据访问策略还是挺值得借鉴.下面就简单总结一下. 访问器 , ...
- Inside Qt Series (全集)
Inside Qt 系列 QObject这个 class 是 QT 对象模型的核心,绝大部分的 QT 类都是从这个类继承而来.这个模型的中心特征就是一个叫做信号和槽(signaland slot)的机 ...
随机推荐
- 微信小程序中target与currentTarget
target在事件流的目标阶段:currentTarget在事件流的捕获,目标及冒泡阶段.但事件流处于目标阶段,target与currentTarget指向一样, 而当处于捕获和冒泡阶段的时候,tar ...
- java基础/一个类A继承了类B,那么A就叫做B的派生类或子类,B就叫基类或超类。
类重复,pulic class demo1 和class demo1 重复 无主类, 在cmd中输入命令: SET CLASSPATH=. (等号后为英文点符号),即可设置解释的路径为当前路径. 再次 ...
- easyui datagrid columns的field支持属性的子属性(field.sonfield形式或者格式化程序形式)
var col=$(_758).datagrid("getColumnOption",_75e);if(col){//var _75f=_75c[_75e];var _75f=un ...
- 【Espruino】NO.07 获取电压值
http://blog.csdn.net/qwert1213131/article/details/27985645 本文属于个人理解,能力有限,纰漏在所难免.还望指正! [小鱼有点电] 前几节的内容 ...
- .NET Core 2.0 官方下载地址及中文教程
开发.net core 应用需要安装.NET Core 2.0 SDK http://www.microsoft.com/net/download/core#/sdk 电脑上运行 .net core ...
- 系列解读Dropout
本文主要介绍Dropout及延伸下来的一些方法,以便更深入的理解. 想要提高CNN的表达或分类能力,最直接的方法就是采用更深的网络和更多的神经元,即deeper and wider.但是,复杂的网络也 ...
- PAT Battle Over Cities [未作]
1013 Battle Over Cities (25)(25 分) It is vitally important to have all the cities connected by highw ...
- 蒙特卡洛模拟(Monte Carlo simulation)
1.蒙特卡罗模拟简介 蒙特卡罗模拟,也叫统计模拟,这个术语是二战时期美国物理学家Metropolis执行曼哈顿计划的过程中提出来的,其基本思想很早以前就被人们所发现和利用.早在17世纪,人们就知道用事 ...
- [LeetCode] 312. Burst Balloons_hard tag: 区间Dynamic Programming
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- Improving the quality of the output
There are a variety of reasons you might not get good quality output from Tesseract. It's important ...