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之设计模式
设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...
随机推荐
- Java 学习 第五篇;面向对象
1:基本数据类型的拆装: 基本变量类型 通过 new WrapperClass(primitive) 创建包装类对象: 包装类的对象 通过 WrapperInstance.XXXValue() 获取包 ...
- Ext常用Tool
Ext.onReady(function() { var mPanel = Ext.create('Ext.panel.Panel', { title: 'Panel', width: '100%', ...
- C语言预处理命令总结大全
C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境.本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性.ANS ...
- 如何理解 css3 的 perspective 属性
一.写在前面的话 最近想多了解一下CSS3的transform 3D效果,transform:英文直译就是转换,它可以实现旋转.缩放.位移等效果,听起来有没有觉得很酷的样子,狠狠的点这里来看看旋转和位 ...
- WordPress SEO ☞ WordPress网站终极优化指南
原文地址:http://www.eastdesign.net/wordpress-seo/ 最新消息,东方设计学院 WordPress SEO 系列视频教程正在持续更新中,目前为了不至于让视频传播过于 ...
- UVA_埃及分数(Hard Version) UVA 12588
Problem EEg[y]ptian Fractions (HARD version)Given a fraction a/b, write it as a sum of different Egy ...
- tr转换或删除字符
字符处理命令:tr —— 转换或删除字符 逐个字符处理而不是处理单词的tr [OPTION]... SET1 [SET2] -d: 删除出现在字符集中的所有字符 tr ab AB
- ASP.NET中连接数据库的各种方法
ASP.NET中连接数据库的各种方法 连接SQL数据库的方法:(一).在Web.Config中创建连接字符串:1.<add name="ConnectionString" c ...
- $.cookie is not a function
在调试网站的时候,用jquery获取cookie时,报错: $.cookie is not a function; 一般情况$.cookie is not a function;错误原因: 一.没有引 ...
- Photoshop 批量处理图片
不论什么你想反复进行的操作都能够通过创建 Photoshop 批处理程序来完毕.比如.你想批量改变图片的大小,就能够通过下面操作来实现. 1.打开随意一张图片,在动作面板中,点击新建button 2. ...