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();
}

 

 

原文地址:https://www.cnblogs.com/james1207/p/3327373.html