以下两段不同程序的比较

//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. Histats安装Counter网站计数器 - Blog透视镜

    Histats提供十分多样性的Counter网站计数器,可以依照你个人的喜好与需求,选择适合的Counter网站计数器,也可以针对同一网站,安装多个Counter网站计数器,作法其实比注册账号时更简单 ...

  2. codecomb 2091【路径数量】

    好久没有更新博客了啊……屯了一堆题没发呢 这是丧心病狂的hzwer每日NOI模拟赛第一天的第一题 妈蛋说好的NOIP难度图论算法两题网络流!让我说什么好 唔……codecomb的页面在晚上就会变得很奇 ...

  3. UESTC_邱老师降临小行星 2015 UESTC Training for Search Algorithm & String<Problem B>

    B - 邱老师降临小行星 Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65536/65535KB (Java/Others) Su ...

  4. apache FtpServer整合spring逻辑处理

    上面我们的部署工作完成了,那么文件上传下载后,ftpserver会自动相应我们的上传下载操作,也就是说ftpServer服务器会得到触发,那么我们如果要得到文件的一些信息,比如说文件的路径.大小.类型 ...

  5. java打印菱形的简单方法

    代码: public class Diamond { /** * 测试main方法 */ public static void main(String[] args) { printDiamond(1 ...

  6. [置顶] Hibernate从入门到精通(五)一对一单向关联映射

    上次的博文中Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理多个相关对象和 ...

  7. 1 游戏逻辑架构,Cocos2d-x游戏项目创建,HelloWorld项目创建,HelloWorld程序分析,(CCApplicationProtocol,CCApplication,AppDeleg

     1 游戏逻辑架构 具体介绍 A 一个导演同一时间仅仅能执行一个场景,场景其中,能够同一时候载入多个层,一个层能够可载多个精灵.层中亦能够加层. B  场景切换 sceneàaddChild(la ...

  8. ubuntu如何开启SSH服务

    ubuntu如何开启SSH服务 分类: Linux 运维与操作基础2013-02-24 13:33 2868人阅读 评论(0) 收藏 举报 sshd ubuntu ubuntu默认并没有安装ssh服务 ...

  9. 关于使用Html5 canvas、 map、jquery构造不规则变色点击区域 热点区域

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. tomcat https jks 沃通免费证书安装 解决方案

    网上百度了一天什么没百度到,最后谷歌到了一篇文章启发之下解决之. 代理谷歌网站推荐一个,可以直接上谷歌: https://www.yundou.info ----------------------- ...