博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt核心剖析:信息隐藏(1)
阅读量:6389 次
发布时间:2019-06-23

本文共 1536 字,大约阅读时间需要 5 分钟。

如果你阅读了 Qt 的源代码,你会看到一堆奇奇怪怪的宏,例如 Q_D,Q_Q。我们的Qt源码之旅就从理解这些宏说起。

下面先看一个C++的例子。

 
  1. class Person     
  2. {     
  3. public:     
  4.     Person(){}     
  5.     ~Person(){}     
  6.     string name();     
  7.     void setName(string name);     
  8.     int age();     
  9.     void setAge(int a);     
  10. private:     
  11.     string _name;     
  12.     int _age;     
  13. };   

这是一个很普通的 C++ 类 Person,他有两个属性 name 和 age。我们试想一下,这个类要怎么去使用呢?如果你不想给我源代码,那么至少也要给我一个 dll 或者其他类似的东西,并且你要把这个头文件给我,这样我才能把它 include 到我的代码中使用。我只能使用你暴露给我的 public 的接口。按理说,private 的东西我是不应该知道的,但是现在我知道了!为什么呢?因为我会去读这个头文件,我知道了,原来在 Person 中,age 就是一个 int,name 就是一个 string。这是你不希望看到的,因为既然你把它声明成了 private 的,就是不想让我知道这些东西。那么怎么办呢?嗯,我有一个解决方案。来看下面的代码:

person.h

 
  1. class Person     
  2. {     
  3. public:     
  4.     Person(){}     
  5.     ~Person(){}     
  6.     string name();     
  7.     void setName(string name);     
  8.     int age();     
  9.     void setAge(int a);     
  10. private:     
  11.     PersonPrivateData *data;     
  12. };    

persondata.cpp

 
  1. class PersonPrivateData     
  2. {     
  3. public:     
  4.     string name;     
  5.     int age;     
  6. };   

怎么样?在 person.h 中看不到我是怎么存储的数据了吧?嗯嗯,也许你很聪明:我还可以在 persondata.cpp 中找到那些声明啊!当然,这是C++语法规定的,我们已经左右不了——但是,我为什么非要把 cpp 文件一并给你呢?因为你使用我的类库的话完全不需要使用 cpp 文件啊。

这就是一种信息隐藏的方法。看上去很麻烦,原本很简单的对 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。

本文转自 FinderCheng 51CTO博客,原文链接:

http://blog.51cto.com/devbean/325581

转载地址:http://gzcha.baihongyu.com/

你可能感兴趣的文章
iOS Swift编程语言
查看>>
Android 实现闹钟功能
查看>>
graal
查看>>
Win10 安装msi 提示2502、2503的错误代码 -- 命令提示符(管理员) -- msiexec /package...
查看>>
Vue.js 使用 Swiper.js 在 iOS < 11 时出现错误
查看>>
Underscore实例教程
查看>>
Nodejs+Express学习二(Mongoose基础了解)
查看>>
MySQL 性能监控4大指标——第一部分
查看>>
几种常见排序算法
查看>>
听我说说我的博客: 月访问量过万的个人IT博客的技术史
查看>>
数组去重的正确编写姿势
查看>>
Emulator 29.0.3 Canary 发布,Android 模拟器
查看>>
Ruby 3 有望引入静态类型
查看>>
Purism 发布 PureBoot:高度安全、完整的 Linux 引导流程
查看>>
JAVA学习day05
查看>>
行业观察(一)| 从渠道为王到数据为王——浅谈服装零售企业的数字化转型 ...
查看>>
阿里架构师,讲述分布式架构云平台解决方案(附学习路线) ...
查看>>
Android 访问WebService
查看>>
老生常谈 String、StringBuilder、StringBuffer
查看>>
SpringMVC工作原理
查看>>