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之设计模式
设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...
随机推荐
- ubuntu 安装openproj-1.4-2.noarch.rpm
一 openproj是rpm包,ubuntu下需要转成deb安装.具体步骤1:下载:http://sourceforge.net/projects/openproj/2:安装alien sudo ap ...
- hdu 4620 Fruit Ninja Extreme
Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 一起来学canvas (前言)
codeyy - 一依丫丫 一起来学canvas (前言)
- 关闭ubuntu apport
apport就是ubuntu上的"crash report"服务,就是当有程序崩溃时弹出的那个发送error report的程序: 个人觉得此功能无用,本着给我的老本子节省资源的思 ...
- 【转】android camera(四):camera 驱动 GT2005
关键词:android camera CMM 模组 camera参数 GT2005 摄像头常见问题 平台信息: 内核:linux系统:android 平台:S5PV310(samsung exyn ...
- 水务新、老营收系统大PK
今天想撩一下咱水务界的大拿——营业收费管理系统. 营业收费 随着城市供水规模的不断扩大及户表改造的深入以及阶梯水价的实行还有移动平台等第三方支付的蓬勃发展,原有的营收软件系统已经不能适应目前水司的管理 ...
- 在浏览器中输入Google.com并且按下回车之后发生了什么?
作者: skyline75489 来源: skyline75489的博客 发布时间: 2015-03-26 16:57 阅读: 4163 次 推荐: 23 原文链接 [收藏] ...
- SQL Performance Improvement Techniques(转)
原文地址:http://www.codeproject.com/Tips/1023621/SQL-Performance-Improvement-Techniques This article pro ...
- 网页嵌入WMP代码(转)
网页嵌入WMP代码 播放器代码解释,装了9.0或9.0以上的播放器才能正常使用: OBJECT id="WMP" height="176" width=&quo ...
- c++网络通信(与服务器通信聊天)和c#网络通信
c++网络通信(有待整理) 链接:http://pan.baidu.com/s/1i3nMLKT 密码:ksi8 c#网络通信(tcp/udp两部分) TCP发送端: using System; us ...