Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
来源:互联网 发布:js同时获取多个id 编辑:程序博客网 时间:2024/06/04 19:51
这两个宏在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
- Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
- Q_D Q_D Q_DECLARE_PRIVATE Q_DECLARE_PUBLIC
- QT中私有公有化(Q_DECLARE_PUBLIC Q_DECLARE_PRIVATE)原理小DEMO
- 与
- 与
- “” 与 “”
- ##与#
- >> 与 > >
- :与::
- &与&&
- && 与 &
- [[与((
- >>与>>>
- *与++
- *与++
- ++与++
- POSIX线程同步
- PHP验证码不显示
- 神经机器翻译(Neural Machine Translation)系列教程
- 动态规划:HDU2844-Coins(多重背包的二进制优化)
- 系统数据字典数据模型设计
- Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
- 006
- 单例模式
- linux常用命令 文件操作类
- (1)OFBIZ-安装部署
- Qt Charts编译和使用
- CRC循环冗余校验码
- xml基础知识(3)
- GDB 调试出现:Couldn't find general-purpose registers in core file