博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC
阅读量:7010 次
发布时间:2019-06-28

本文共 1721 字,大约阅读时间需要 5 分钟。

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
(qGetPtrHelper(d_ptr)); } \ inline const Class##Private* d_func() const { return reinterpret_cast
(qGetPtrHelper(d_ptr)); } \ friend class Class##Private; #define Q_DECLARE_PUBLIC(Class) \ inline Class* q_func() { return static_cast
(q_ptr); } \ inline const Class* q_func() const { return static_cast
(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的原因

转载地址:http://yrttl.baihongyu.com/

你可能感兴趣的文章
Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
查看>>
xmapp 404设置
查看>>
[js - 算法可视化] 汉诺塔(Hanoi)演示程序
查看>>
Note:JSON
查看>>
分享.NET 3.0的书籍下载(持续更新中)
查看>>
几道有意思的逻辑分析题
查看>>
apache svn下新建一个项目
查看>>
高效 JavaScript 单元测试(转)
查看>>
[Windows Azure] What is a cloud service?
查看>>
使用C#的泛型队列Queue实现生产消费模式
查看>>
tomcat发布web项目,支持域名
查看>>
js和Jquery获取选中select值和文本
查看>>
Linux系统排查1——内存篇
查看>>
Java实现注册邮箱激活验证
查看>>
数据库缓存
查看>>
mvc 数据验证金钱格式decimal格式验证
查看>>
常用的Web服务器
查看>>
UPW学习资料整理 .NET C# 转
查看>>
Oracle12c中新建用户
查看>>
分布式编译工具
查看>>