zoukankan      html  css  js  c++  java
  • 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();
    }

     

     

  • 相关阅读:
    纯新手向解题WriteUp—攻防世界Web新手训练12题
    2019-2020-1学期 20192406《网络空间安全专业导论》第十二周学习总结
    2019-2020-1学期 20192406《网络空间安全专业导论》第十一周学习总结
    网络空间安全导论第4章小组讨论
    2019-2020-1学期 20192406《网络空间安全专业导论》第十周学习总结
    网络空间安全导论第3章小组讨论
    2019-2020-1学期 20192406《网络空间安全专业导论》第九周学习总结
    2019-2020-1学期 20192406《网络空间安全专业导论》第八周学习总结
    小组讨论——12-14章
    2019-2020-1学期 20192406《网络空间安全专业导论》第七周学习总结
  • 原文地址:https://www.cnblogs.com/james1207/p/3327373.html
Copyright © 2011-2022 走看看