以下两段不同程序的比较

//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设计模式的理解和使用的更多相关文章

  1. 【设计模式+原型理解】第一章:使用Javascript来巧妙实现经典的设计模式

    刚开始学习设计模式之前,我是没想说要学习设计模式的,我只是因为想学习JS中的原型prototype知识,一开始我想JS中为什么要存在原型这个东西?于是慢慢通过原型而接触到设计模式,后来发现我这个过程是 ...

  2. MVC和MVVM设计模式简单理解

    1.mvc设计模式理解 Model: 模型 持有所有的数据状态和业务逻辑; 泛指数据库,链接数据库,建立数据模型 View: 视图 用来展示数据模型在页面上,泛指前端 Controller: 控制器, ...

  3. java 23种设计模式 深入理解

    以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...

  4. java 23种设计模式 深入理解【转】

    以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...

  5. DAO设计模式的理解

    为了降低耦合性,提出了DAO封装数据库操作的设计模式. 它可以实现业务逻辑与数据库访问相分离.相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口. 一般的DAO的封装由 ...

  6. 设计模式 --深入理解javascript

    /* 一.单例模式 */ var Universe; (function () { var instance; Universe = function Universe() { if (instanc ...

  7. 【设计模式+原型理解】第三章:javascript五种继承父类方式

    [前言] 我们都知道,面向对象(类)的三大特征:封装.继承.多态 继承:子类继承父类的私有属性和公有方法 封装:把相同的代码写在一个函数中 多态: ->重载:JS严格意义上是没有重载,但可以通过 ...

  8. JavaScript设计模式的简单理解

    设计模式可以理解为一系列的代码框架,我觉得主要涉及封装的概念.把实现某一功能的代码段封装在函数中,可以方便调用,同时利于代码的复用,提高了代码的可维护性.下面简单介绍一下几种设计模式的个人感受. 1. ...

  9. 深入理解javascript之设计模式

    设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...

随机推荐

  1. C# XML序列化帮助类代码

    public static class XmlHelper { private static void XmlSerializeInternal(Stream stream, object o, En ...

  2. CPLD和FPGA的区别(转)

    原文:http://tvb2058.spaces.eepw.com.cn/articles/article/item/15358 本文重点从CPLD的结构来讲的,从而说明其与FPGA的区别 ----- ...

  3. USB信号是什么类型的? 为什么在D+,D-处要接上拉下拉电阻呢,具体阻值要如何计算

    USB协议要求的,1.5K上拉在D+时表示是全速设备,在D-表示不是全速设备有些方案里面(比如PNX5230)推荐D+/D-接下拉1M的电阻是为了提高数据传输稳定性的 ①  usb有主从设备之分,主设 ...

  4. 认识元数据和IL(上) <第三篇>

    说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么 ...

  5. Android中通过代码获取arrays.xml文件中的数据

    android工程res/valuse文件夹下的arrays.xml文件中用于放各种数组数据,比如字符串数组.整型数组等,数组中的数据可能是具体的值,也有可能是对资源数据的引用,下面针对这两种情况通过 ...

  6. canvas.js | CLiPS

    canvas.js | CLiPS canvas.js The canvas.js module is a simple and robust JavaScript API for the HTML5 ...

  7. ZOJ问题(坑死了)

    ZOJ问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  8. Android 代码混淆及第三方jar包不被混淆

    为了保护代码被反编译,android引入了混淆代码的概念 1.设置混淆 在工程下找到project.properties文件 在文件中加入proguard.config=${sdk.dir}/tool ...

  9. VC2010 Working Directory

    VC project setting --〉debug中的working directory指的是工作文件夹在哪里? project属性下,Debug以下的 Working Directory 是为了 ...

  10. Linux FTP安装与简单配置

    1.检測是否原有启动 ps -ef|grep vsftpd 2.检測是否有安装包 rpm -qa|grep vsftpd 3.假设有输出.查看状态并启动 service vsftp status  - ...