PIMPL设计模式的理解和使用
以下两段不同程序的比较
//file a.h
#include "a.h"
#include “ b.h”
class A{
void Fun();
B b;
}
//file:a.cpp
#include "a.h" //无形中也引入了b.h
void A::fun(){
b.fun();//调用类a的fun方法
}
//file: main.cpp
#include"a.h." //无形中也引入了b.h
int main(){
A a;
a.fun();
return 0;
}
由以上代码可以观察到:
1、引入了更多的头文件,降低了编译的速度
main.cpp 和a.cpp中无形中引入了b.h
2、提高了模块的耦合度
a.编译器
b.运行期
假如B类做了改变B类的大小改变了,a.cpp也需要重新编译,重新分配空间.那么也就是A类依赖与B类的实现。
假如B类有子类,则在运行期中不能使用多态的功能,也就是B类在此前情况不能被其子类更换。那么这样就提高了模块的耦合度
3、降低了接口的稳定程度
a、对于库的使用,方法不能改变
b、对于库的编译,动态库的变更,客户程序也需要重新编译
意思是:把a.h和a.cpp编译成动态库,mai.cpp当作客户程序。如何动态库改变,客户程序也需要重新编译。类A发生改变了,main.cpp也需要重新编译。客户程序不仅仅依赖于接口还依赖与类A了。
出现的以上问题可以用PIMPL思想来解决。
PIMPL(private implementation或pointer to implementation)也称为handle/body idiom
PIML背后的思想是把客户与所有关于类的私有部分的知识隔离开。避免其它类知道其内部结构
可利用指针来解决:
1、降低编译依赖、提高重编译速度
a、因为指针对于32为的系统来说大小是4,64的系统来说是大小是8,这是相对稳定的。
b、即使类B发生改变,指针的大小也不会发生改变。文件a.h也不需要重编译
c、利用指针以后a.h不需要包含b.h,只需要进行前向声明。
d、main.cpp包含了a.h但a.h中没有包含b.h,不依赖于b.h
e、假如类B有子类,可以在在运行期间通过指针调用B类的子类,进行调用实现多态的功能。
2、接口和实现分离
通过使用指针,其所指的类的实现进行分离了,不关心类B的实现,指针的大小是固定的。
3、降低模块的耦合度
a.编译期
main.cpp包含了a.h但a.h中没有包含b.h,不依赖于b.h
b.运行期
假如类B有子类,可以在在运行期间通过指针调用B类的子类,进行调用实现多态的功能。
4、提高了接口的稳定程度
a、对于库的使用,方法不能改变
b、对于库的编译,动态库的变更,客户程序不用重新编译
如果把a.h和a.cpp编译成动态库,mai.cpp当作客户程序,假如类B发生改变但是其指针大小并没改变,库也没有改变,所以客户程序不用重新编译。那么在软件升级的过程中,只需要升级动态库即可,客户程序不需要改变。
该指针也可以是智能指针,那么智能指针所持有的对象发生改变,那么智能指针的大小也不会发生改变,其大小或是4或是8
// file a.h
class B;//前向声明
class A {
public:
A(){}
~A(){}
void Fun();
B* b_;
};
// file a.cpp
#include "a.h"
#include “b.h"//b.h只需要包含一次
A::A() : px_( new A ) {
}
A::~A() {
delete b_;
b_ = 0;
}
void A::Fun {
b_->Fun();
}
// file main.cpp
#include “a.h” //没有包含b.h
int main(void)
{
A a;
a.Fun();
}
PIMPL设计模式的理解和使用的更多相关文章
- 【设计模式+原型理解】第一章:使用Javascript来巧妙实现经典的设计模式
刚开始学习设计模式之前,我是没想说要学习设计模式的,我只是因为想学习JS中的原型prototype知识,一开始我想JS中为什么要存在原型这个东西?于是慢慢通过原型而接触到设计模式,后来发现我这个过程是 ...
- MVC和MVVM设计模式简单理解
1.mvc设计模式理解 Model: 模型 持有所有的数据状态和业务逻辑; 泛指数据库,链接数据库,建立数据模型 View: 视图 用来展示数据模型在页面上,泛指前端 Controller: 控制器, ...
- java 23种设计模式 深入理解
以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...
- java 23种设计模式 深入理解【转】
以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...
- DAO设计模式的理解
为了降低耦合性,提出了DAO封装数据库操作的设计模式. 它可以实现业务逻辑与数据库访问相分离.相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口. 一般的DAO的封装由 ...
- 设计模式 --深入理解javascript
/* 一.单例模式 */ var Universe; (function () { var instance; Universe = function Universe() { if (instanc ...
- 【设计模式+原型理解】第三章:javascript五种继承父类方式
[前言] 我们都知道,面向对象(类)的三大特征:封装.继承.多态 继承:子类继承父类的私有属性和公有方法 封装:把相同的代码写在一个函数中 多态: ->重载:JS严格意义上是没有重载,但可以通过 ...
- JavaScript设计模式的简单理解
设计模式可以理解为一系列的代码框架,我觉得主要涉及封装的概念.把实现某一功能的代码段封装在函数中,可以方便调用,同时利于代码的复用,提高了代码的可维护性.下面简单介绍一下几种设计模式的个人感受. 1. ...
- 深入理解javascript之设计模式
设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...
随机推荐
- 关于SQL SERVER 2008 R2发布订阅功能
实现功能:主服务器维护数据的变更,从服务器需要时同步主服务器的数据. 配置:主从服务器均为SQL SERVER 2008 R2. 实现方法: 预备: 1.主从服务器需建立同一账户名及密码的账户(当时我 ...
- WPF笔记(1.8 资源与映射)——Hello,WPF!
原文:WPF笔记(1.8 资源与映射)--Hello,WPF! 终于,看明白了,已经是凌晨1:39分.这本书这一节写得实在是不好,一个local搞得我糊里糊涂,于是,准备按照他的思路,按照我的理解,改 ...
- POJ1094 Sorting It All Out(拓扑排序)
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30110 Accepted: 10 ...
- C++ classics
common Business-Oriented LanguageBASIC(Beginner's All-purpose Symbolic Instruction Code)1972 C1983 C ...
- HBase 4、Phoenix安装和Squirrel安装
描述 现有hbase的查询工具有很多如:Hive,Tez,Impala,Shark/Spark,Phoenix等.今天主要记录Phoenix. phoenix,中文译为“凤凰”,很美的名字.Phoen ...
- js跳转页面代码用法
一:window.location.href='https://www.baidu.com'; 需要加上http或者https,否则会查找项目内htm打开. 二:window.history.bac ...
- Mac 下纯lua(一)
Lua 介绍 什么是lua - lua是一种跨平台开发脚本语言. Lua 历史 学校 University of Rio de Janeiro 国家 巴西 作者 Roberto Ierusalimsc ...
- HDU 1559 最大子矩阵 (DP)
题目地址:pid=1559">HDU 1559 构造二维前缀和矩阵.即矩阵上的点a[i][j]表示左上方的点为(0,0),右下方的点为(i,j)的矩阵的和.然后枚举每一个矩阵的左上方的 ...
- 在apache2.4版本之前做客户端访问控制,是用Allow Deny Order指令做访问控制的,
在apache2.4版本之前做客户端访问控制,是用Allow Deny Order指令做访问控制的,而在2.4的版本上是用的用法跟之前的版本大不相同,如下 ###################### ...
- C语言undefined behaviour未定义行为
C语言中的未定义行为(Undefined Behavior)是指C语言标准未做规定的行为.同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又 ...