一、回顾
使用qt2年多了,但是还是觉得很陌生,总是会被qt搞的很紧张,有时候当我自信满满的打开帮助文档,搜索某个已知的类时,由于笔误敲错了一个字母而出现了另外一个类,不过奇怪的是还真有这么一个类,哎!!!我怎么都不知道呢!看来qt的东西还真不是一般的多,随便一个笔误都可能发现新的东西。特别是qt现在已经发布了qt5.7版本,相对于qt4的时代那真是天差地别,就我个人而言,我现在用的是qt5.6.1-1,因为qt5.6版本官方声称维护2年的时间。qt5.6取消了webkit模块,如果需要使用可以自行编译,我自己也对qt5.6.1-1的整个模块进行了编译,有需要的小伙伴可以参考msvc2013编译qt5.6源码
本文主要是想讲述qt的一个代码书写方式,当然了这样说有些大,其实就是qt他的源码在分层上是把成员都单独拉到一个filename_p.h的头文件里,这样做的有好处也有坏处,下面是我自己的观点:
优点 | 缺点 | |
qt |
1、庞大的代码容易管理 2、成员的私有实现和具体对外开放的接口分离 |
1、阅读性差 2、可扩展性差 |
表1 qt优缺点
上述缺点都是我个人认为,其中可扩展性差不是说qt不能扩展,而是扩展的时候有一定限制,因为qt的一个功能实现的最基本单元就是filename.h、filename.cpp和filename_p.h,通常情况下我们只能拿到filename.h,而私有的filename_p.h文件拿不到,所以不能进行对齐进行扩展,这也导致了一些操作不能很好的而进行,除非qt源码给我们了相关接口,否则我们是很难去维护私有的filename_p.h的实现,比如:qt的qcharts模块,这个模块是qt5.7才正式开源的模块,当然了有兴趣的同学可以自己手动在自己的当前qt模块下编译qtcharts,然后将开发所需要的库都加入到自己当前的qt版本中。
为什么说提到qcharts模块呢,是因为我之前看过大概的实现原理,他也是一贯的qt代码作风,那就是不容易阅读,每一个对外暴露的接口,仅仅是接口而已,而他具体的实现都是隐藏在另外一个没有暴露给用户的接口里,如下图1所示,QBarSeries是对外开放的接口,但是其具体实现是在BarSeries内完成的,这样就导致了我们只能对QBarSeries进行重写,而不能修改BarSeries类,或者对齐进行重写。
图1 QBarSeries帮助文档
呵呵呵。。。说的有些多了,可能喜欢qt的人会来骂我,以上完全是我个人的理解,有不对的地方请指正。其实我个人还是挺喜欢qt的,最起码在封装上我觉得很好,接口的命名上也很容易理解,比较容易上手,对于一个做C++界面工作的开发来说,算是一个不错的选择。
下面进入本片文章的主题,本片文章我主要是想分析下qt的私有实现结构,其实也就是我们所谓的impl实现原则。
二、思路
说起qt的代码管理,我觉着真的非常好,毕竟是第一个庞大的库,如果没有一个优秀的代码结构,对于C++这样编译性的语言,那真的是一个噩梦,多么优秀的程序员可能一天就处于编译代码的等待中。。。
qt在类的管理上,讲成员函数单独封装到了一个对于的_p.h的头文件中,然后可能还是提供相应的私有接口,为什么说私有呢,因为我们拿不到,但是qt的类中却可以拿到,这个在下一节中我会做一些简单的分析。
qt代码分工:filename.h、filename.cpp和filename_p.h,而这3个文件是用一组宏类关联起来,并使用,有一定的封装性。后续文章中,filename.h中的类我就用Class描述,filename_p.h中的类我就用ClassPrivate描述。
三、关键宏
- Q_DECLARE_PUBLIC
- Q_DECLARE_PRIVATE
- Q_D
- Q_Q
1、Q_DECLARE_PUBLIC
这个宏是用来在filename_p.h类中使用得,为的就是可以拿到一个Class的类的一个指针,并且它是Class的友元类,Class类是一个泛指,指的是filename.h纵的类。
#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;
2、Q_DECLARE_PRIVATE
这个宏是在filename.h类中使用,和Q_DECLARE_PUBLIC宏是对于的,它是ClassPrivate类的友元,并且可以拿到一个ClassPrivate的指针
#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;
3、Q_D和Q_Q
这两个宏就比较好理解了,仅仅是快捷的拿到一个指针,关于这个指针是怎么声明?在哪儿声明?后续都会提到
#define Q_D(Class) Class##Private * const d = d_func() #define Q_Q(Class) Class * const q = q_func()
四、结构说明
首先我先来回答一下,第三节中第三小节所提到的问题,关于Class和ClassPrivate这两个指针存储的地方,就是他们分别的功能基类,而且必须是保护或者是公有成员。在后续的子类中都不需要再声明该类指针
作为父类都必须提供至少两个构造函数,一个是用来声明对象自己的,一个是用来初始化子类的,这样说可能会有点儿不好理解,那么我就把qwidget的源码搬上来做以说明
图1 QWidget公有构造函数
aaarticlea/png;base64,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" alt="" />
图2 QWidget保护构造函数
图1和图2分别是QWidget的两个构造函数,只是访问权限不一样,保护函数只能在子类中访问,那么同学们是不是有些明白了,基类的ClassPrivate就是通过这个保护的构造方法类初始化,子类传递给父类的ClassPrivate指针,能赋值给父类的成员指针,那么这个指针肯定有父子关系的,那么又一个关键点浮出水面,那就是ClassPrivate也是可以继承的,这样很好的达到了私有数据继承的问题,如图3就是调用了子类的私有结构来初始化父类私有结构
图3 子类构造函数
零散的说了这么多,qt二进制兼容性也说了个大概,只是没有系统的demo,那么下面我贴一个完整的测试头文件夹,关于demo,后续我会给一个完整的
struct BasicPlotPrivate;
//基类 保存私有结构指针 并提供一个保护的构造函数
class BasicPlot : public QWidget
, public PlotCallback
{
Q_OBJECT
Q_DECLARE_PRIVATE(BasicPlot) protected:
BasicPlot(QWidget * parent = nullptr);
public:
~BasicPlot(); protected:
BasicPlot(BasicPlotPrivate & pd, QWidget * parent = nullptr); protected:
QScopedPointer<BasicPlotPrivate> d_ptr;
};
//基类的私有结构 保存一个基类指针
struct BasicPlotPrivate
{
Q_DECLARE_PUBLIC(BasicPlot) BasicPlot * q_ptr;
};
//子类 不需要声明指针 公有构造函数实现类似于图3
class FinancialPlot : public BasicPlot
{
Q_OBJECT
Q_DECLARE_PRIVATE(FinancialPlot) protected:
FinancialPlot(QWidget * parent = nullptr); public:
~FinancialPlot(); protected:
FinancialPlot(FinancialPlotPrivate & pd, QWidget * parent = nullptr);
};
//子类私有结构 继承与父类私有结构
struct FinancialPlotPrivate : public BasicPlotPrivate
{
FinancialPlotPrivate() : BasicPlotPrivate(){}
Q_DECLARE_PUBLIC(FinancialPlot)
};
五、示例下载
关于示例下载,我将会在下一节qcustomplot使用分享中提供一份demo,而这个dmeo的实现就是使用的qt这种代码组织方式。
补充: