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 ...
随机推荐
- Codeforces 1137F Matches Are Not a Child's Play [LCT]
Codeforces 很好,通过这题对LCT的理解又深了一层. 思路 (有人说这是套路题,然而我没有见过/kk) 首先发现,删点可以从根那里往下删,非常难受,所以把权值最大的点提为根. 然后考虑\(x ...
- C++ 如何进阶?
1.C++的用途和意义 总体来说,C++作为一门软件开发语言,它的流行度是在减少的.主要原因在于语言的复杂和灵活导致软件开发成本提高,这体现在开发周期和人力上.它不适用于startup公司的快速开发, ...
- 深度Linux /etc/profile 环境变量生效问题
/etc/profile 环境变量生效问题 设置了环境变量后 ,使用source /etc/profile生效后,每次关闭终端后,都需要重新输入source /etc/profile命令使环境变量生效 ...
- ElasticSearch : 基础简介
1.安装 我用的docker安装,这个用起来比较方便,我是在腾讯云部署的docker,具体的过两天总结一下 安装: docker pull elasticsearch 运行: docker run - ...
- 第十四周助教工作总结——NWNU李泓毅
助教博客链接:https://www.cnblogs.com/NWNU-LHY/ 本次作业的要求:团队项目需求改进与系统设计:https://www.cnblogs.com/nwnu-daizh/p/ ...
- python面向对象继承
class A(object):pass # 括号中可称为父类,基类,超类 class B:pass # 父类,基类,超类 class A_son(A,B):pass # 子类,派生类 class A ...
- Linux服务器下日志截取
我们经常需要去Linux服务器上查看服务运行日志,但是有时候日志文件很大看起来很不方便,这个时候我们需要对日志进行切割筛选出自己需要的日志,比如查看某段时间内的日志,命令如下: sed -n '/ ...
- Tosca : 扩展dll动态语言 识别点击下拉, 识别成table
放到这 配置 重启 tosca command
- 【E2E】Intel AI DevCloud 的申请和登陆
参考:https://www.cnblogs.com/WaitingForU/p/9091096.html 一.注册 https://www.cnblogs.com/WaitingForU/p/909 ...
- FFmpeg 参数详解(二)
https://blog.csdn.net/yizhizouxiaqu/article/details/52233673 5.参数选项 如果没有特殊声明,所有的数字参数都以一个字符串代表数字的形式作为 ...