QT 源码分析--1
Ref: http://blog.sina.com.cn/s/blog_6e80f1390100qoc0.html
安装qt之后(我使用的是online自动安装),安装目录下有\5.10.1\Src\qtbase\src目录, 这里的所有文件夹名都对应着 Qt 的模块的名字 :gui,network等。
我们从最核心的 QtCore 开始,这个模块对应的是corelib文件夹。之所以选择 QObject,一是因为它是 Qt 的核心类,另外一个很重要的原因是,QObject类是一个典型的Qt类,我们可以通过这个类学习到Qt的设计思路。
编写 Qt 代码的时候,使用的语句是 #include<QObject>, 对应的是QObject文件,该文件的位置可以在qt creator中用ctrl+鼠标查看,具体目录为\5.10.1\mingw53_32\include\QtCore,该文件中只有一句话:#include "qobject.h",qobject .h的位置为 \5.10.1\Src\qtbase\src\corelib\kernel,在该kernel文件夹下,可以找到有四个文件以 qobject 打头:
qobject.h:QObject 的类定义,这个就是QObject 文件引用的文件,也就是我们使用的实际头文件;
qobject.cpp:QObject的实现代码;
qobjectdefs.h:这个文件中定义了很多用到的宏,并且定义了QMetaObject类,而这个类是实现signal-slot的基础;
qobject_p.h:对 QObject的辅助数据类;
还会看到另外两个文件:qobjectcleanuphandler.h 和qobjectcleanuphandler.cpp。不过如果打开这两个文件就会发现,这里面定义的是一个QObjectCleanupHandler类,而这个类是继承了 QObject 的,因此这只是一个普通的工具类,不在我们目前的讨论之列。因此我们可以认为,QOjbect类是由4个文件共同实现的:qobject.h,qobject.cpp,qobjectdefs.h和qobject_p.h。
/////////////////类成员变量的封装方法: //////////////////////////
下面先看一个C++的例子。
这是一个很普通的 C++ 类 Person,他有两个属性 name 和age。这个类要怎么去使用呢?如果你不想给我源代码,那么至少也要给我一个 dll或者其他类似的东西,并且你要把这个头文件给我,这样我才能把它 include 到我的代码中使用。我只能使用你暴露给我的 public的接口。按理说,private 的东西我是不应该知道的,但是现在我知道了!为什么呢?因为我会去读这个头文件,我知道了,原来在Person 中,age 就是一个 int,name 就是一个 string。这是你不希望看到的,因为既然你把它声明成了private 的,就是不想让我知道这些东西。那么怎么办呢?嗯,我有一个解决方案。来看下面的代码:
person.h
persondata.cpp
在 person.h 中看不到我是怎么存储的数据了吧?嗯嗯,也许你很聪明:我还可以在 persondata.cpp中找到那些声明啊!当然,这是C++语法规定的,我们已经左右不了——但是,我为什么非要把 cpp文件一并给你呢?因为你使用我的类库的话完全不需要使用 cpp 文件啊。----------------我看到5.10.1的qobject.h里面包含了 QObjectData类的定义,难道5.10.1没有对object类的数据成员进行掩盖,直接全部暴露?
这就是一种信息隐藏的方法。看上去很麻烦,原本很简单的对 name 和 age的访问都不得不通过一个指针去访问它,何必呢?其实这样做是有好处的:
- 减少头文件的依赖。像这样我们把数据成员都写在 cpp 文件中,当我们需要修改数据成员的时候就只需要修改 cpp文件。虽然都是修改,但这和修改 .h 文件是不一样的!原因在于,如果 .h 文件发生改变,编译器会重新编译所有 include 了这个.h 文件的文件。如果你这个类相当底层,那就会花费很长时间。
- 增加类的信息封装。这意味着你根本看不到具体数据类型,必须使用 getter 和 setter 去访问。我们知道 C++ 有一个typedef 语句,我定义一个数据类型 ABC,如果你看不到具体文件,你会知道这个 ABC 是 string还是 int 么?
这就是 C++ 的一种设计方法,被称为 Private Class,大约就是私有类吧!更确切地说应该是私有数据类。据说,这也是Qt 2.x 的实现方式。但是如果你去看你的 Qt SDK代码,你是看不到这样的语句的,取而代之的则是一些我们开头所说的 Q_D这些宏。或许你已经隐隐约约地猜到了,这些宏就是实现这个的:Private Data。
下面在上一篇的基础上,我们进入Qt的源代码,看看Qt4.x是如何实现 Private Classes 的。
QT 源码分析--1的更多相关文章
- Qt源码分析之QObject
原文:http://blog.csdn.net/oowgsoo/article/details/1529284 我感觉oowgsoo兄弟写的分析相当透彻,赞! 1.试验代码: #include < ...
- QT源码分析(从QApplication开始)
QT源码分析 转载自:http://no001.blog.51cto.com/1142339/282130 今天,在给同学讲东西的时候,谈到了Qt源代码的问题,才发现自己对Qt机制的了解是在太少了,而 ...
- QT源码分析:QObject
QT框架里面最大的特色就是在C++的基础上增加了元对象系统(Meta-Object System),而元对象系统里面最重要的内容就是信号与槽机制,这个机制是在C++语法的基础上实现的,使用了函数.函数 ...
- QT源码分析:QTcpServer
最近在看有关IO复用方面的内容,自己也用标准c++库实现了select模型.iocp模型.poll模型.回过头来很想了解QT的socket是基于什么模型来实现的,所以看了QT关于TcpServer实现 ...
- Qt源码分析之信号和槽机制
Qt的信号和槽机制是Qt的一大特点,实际上这是和MFC中的消息映射机制相似的东西,要完成的事情也差不多,就是发送一个消息然后让其它窗口响应,当然,这里的消息是广义的说法,简单点说就是如何在一个类的一个 ...
- Qt源码分析之信号和槽机制(QMetaObject是一个内部struct)
Qt的信号和槽机制是Qt的一大特点,实际上这是和MFC中的消息映射机制相似的东西,要完成的事情也差不多,就是发送一个消息然后让其它窗口响应,当然,这里的消息是广义的说法,简单点说就是如何在一个类的一个 ...
- Qt源码分析之QPointer
QPointer是一个指针封装类,其作用类似于智能指针,但是它最大的特点应该是在指针的控制上,它希望一个Qt的指针(当然是从QObject派生的)可以同时被多个类拥有,这在界面编程中当然是很常见的事情 ...
- Qt之使用setWindowFlags方法遇到的问题(追踪进入QWidget的源码分析原因,最后用WINAPI解决问题)good
一.简述 前段时间在使用setWindowFlags方法时遇到了一个坑,具体情况是想通过窗口界面上一个checkBox来控制窗口当前状态是否置顶,而Qt提供了Qt::WindowStaysOnTopH ...
- Qt update刷新之源码分析(一)
在做GUI开发时,要让控件刷新,会调用update函数:那么在调用了update函数后,Qt究竟基于什么原理.执行了什么代码使得屏幕上有变化?本文就带大家来探究探究其内部源码. Qt手册中关于QWid ...
随机推荐
- ModuleNotFoundError: No module named 'cv2'
pip3 install opencv-python
- linux管道pipe详解
linux管道pipe详解 https://blog.csdn.net/qq_42914528/article/details/82023408
- CF1215题解
E 假设从小到大排序,每次交换相邻两个,最小次数即冒泡排序也就是逆序对 考虑值域较小,把每个值映射到\([1,20]\) 设\(f_i\)为已经加入集合为\(i\)的值的最小逆序对个数,考虑填表法 即 ...
- Coupled和segregated【转载】
转载自:http://blog.sina.com.cn/s/blog_67873f6c0100ltq6.html 问题1: 我看中文帮组里说是'分离'的意思?我绝对翻译不太好,请问有更好的翻译吗? 和 ...
- 第一步,怎么打开react的大门?
前言 其实我的react的实战经验很少,大概是17年-18年写了一个react全家桶的后台管理系统.猜测这个项目应该还一直在使用 在我手里的vue项目就比较多了,技术栈一直是vue全家桶.最近也在深入 ...
- kubernetes入门学习系列
一.kubernetes基础概念 初识kubernetes kubernetes相关概念 二.kubernets架构和组件 kubernetes架构 kubernetes单Master架构 kuber ...
- ubuntu之路——day7.4 梯度爆炸和梯度消失、初始化权重、梯度的数值逼近和梯度检验
梯度爆炸和梯度消失: W[i] > 1:梯度爆炸(呈指数级增长) W[i] < 1:梯度消失(呈指数级衰减) *.注意此时的1指单位矩阵,W也是系数矩阵 初始化权重: np.random. ...
- 修改layui的表单手机、邮箱验证可以为空怎么实现?
修改layui的表单手机.邮箱验证可以为空 解决办法: 修改源码: 把表单验证源代码(form.js)的正则表达式改一下,例如手机的正则为:/^1d{10}$/,可以改成/^$|^1d{10} ...
- TP5.1框架最后登录时间不会更新
最后登录时间:2019-5-1 14:44 发现系统管理员时间总是停留在这个时间,后来才发现原来是时间没有自动更新. 手册地址:https://www.kancloud.cn/manual/thi ...
- Nessus提示API Disabled错误
Nessus提示API Disabled错误 在浏览器中打开Nessus,如果长时间没有操作,就会造成会话过期失效.这时,如果直接访问,就会提示API Disabled错误.这个时候,需要刷新页面 ...