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 ...
随机推荐
- 《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)
新手入门:关于C++中的内联函数(inline) 在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数. 可能说到这里,很 ...
- Three.js中的group,obj,模型中layers层级与相机
目录 Three.js中的group,obj,模型中layers层级与相机 layers group中的.layers.mask设置 一些设想 Three.js中的group,obj,模型中layer ...
- FCS省选模拟赛 Day5
传送门 Solution Code #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?( ...
- 统计单词Java
功能0:输出某个英文文本文件中 26 字母出现的频率,由高到低排列,并显示字母出现的百分比,精确到小数点后面两位. 功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字 ...
- <c:choose>
备注一下属性 DIV没有VALUE属性 <c:choose> <c:when test="${yggModel.type=='0'}">食品< ...
- etcd,flannel,docker relationship---and k8s
journalctl -xe voidcn.com/article/p-qufvdmpq-bqn.html etcd more etcd.confETCD_NAME=default ETCD_DATA ...
- 后端小白的Bootstrap笔记 一
栅格系统 下面这张图是Bootstrap对栅格系统有关系数的规定 什么是栅格体统? 栅格系统是Bootstrap提供的移动优先的网格系统, 各个分界点如上: 576px 720px 992px 120 ...
- 【转】反编译微信小程序错误: $gwx is not defined和__vd_version_info__ is not defined 已解决
修改wxappUnpacker文件中的 wuWxss.js function runVM(name, code) { // let wxAppCode = {}, handle = {cssFile: ...
- 前端 MV*框架的意义
早期前端都是比较简单,基本以页面为工作单元,内容以浏览型为主,也偶尔有简单的表单操作,基本不太需要框架. 随着 AJAX 的出现,Web2.0的兴起,人们可以在页面上可以做比较复杂的事情了,然后前端框 ...
- Redux遵循的三个原则是什么?
(1)单一事实来源: 整个应用的状态存储在单个 store 中的对象/状态树里.单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序. (2)状态是只读的: 改变状态的唯一方法是去触发一个动作 ...