篇一:
Qt之q指针(Q_Q)d指针(Q_D)源码剖析---源码面前了无秘密_qtq指针-CSDN博客
通常情况下,与一个类密切相关的数据会被作为数据成员直接定义在该类中。然而,在某些场合下,我们会将这些数据从该类(被称为公类)分离出来,定义在一个单独的类中(被称为私类)。公类中会定义一个指针,指向私类的对象。在计算机的发展历史中,这种模式被称为pointer to implementation (pimpl)。
Qt常将其命名为d_ptr或者d。Qt文档将其称为d-pointer。与之对应还有q_ptr或者q。
所以,q,d指针并不是多么神秘,它只是运用了pimpl手法,将数据成员放到了另外一个类中。
那么接下来,在了解了pimpl手法后,可以看下面的d,q指针了。
Q_D和Q_Q指针
在一些项目中会遇到这两者,简称 D 指针和 Q 指针。Qt中大量使用Q_D和Q_Q。
Q_D 与 Q_Q宏定义
#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 两个指针变量。
=》双井号:连接作用,直接替换类名就行。Q_D(QFocusFrame)返回的是Class##Private * const 类型指针,替换掉Class后,就是QFocusFramePrivate* const 类型指针,即为d指针!
Q_DECLARE_PRIVATE 与 Q_DECLARE_PUBLIC
那么 d_func() 和 q_func()又是什么呢?那就需要看这两个宏的定义
#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 cons