开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1438|回复: 0
收起左侧

[其它] C++程序的设计机制2 Pimpl机制

[复制链接]

发表于 2013-2-21 20:46:23 | 显示全部楼层 |阅读模式   北京市北京市
pImpl惯用手法的运用方式大家都很清楚,其主要作用是解开类的使用接口和实现的耦合。本文从Pimpl机制分析开始讲起,一起来看。



Pimpl机制是Private Implementation的缩写,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们一般都会修改私有接口,但是这会导致包含该头文件的所有源文件都要重新编译,这会是个麻烦事儿。Pimpl机制,顾名思义,将实现私有化,力图使得头文件对改变不透明。
机制分析
首先,我们先看看不使用这个机制的一个实现:


    // MyBase.h  
  • class MyBase {  
    public:  
  • int foo();  
    };  
  • // MyDerived.h  
    #include "MyBase.h"  
  • class MyDerived : public MyBase {  
    public:  
  • int bar();  
  • };

假设你现在希望在MyBase.h中加入一个新的private和protected成员函数,那么MyDerived和所有包含MyBase.h的源文件都需要重新编译。在一个大工程中,这样的修改可能导致重新编译时间的激增。你可以使用Doxygen或者SciTools看看头文件依赖。
一般来说,不在头文件中包含头文件是一个比较好的习惯,但是这也不能完全消除修改MyBase.h带来的重新编译代价。有没有一个机制可以使得对私有接口做修改时我们可以减小重新编译的代价。
在Pimpl机制中,我们使用前置声明一个Impl类,并将这个类的一个指针实例放入主类中,如下:


    // MyClass.h  
  • class MyClassImpl; // forward declaration  
    class MyClass {  
  • public:  
    MyClass();  
  • ~MyClass();  
    int foo();  
  • private:  
    MyClassImpl *m_pImpl;  
  • };

现在,除非我们修改MyClass的公有接口,否则这个头文件是不会被修改了。然后,我们用这个Impl类的实现来完成主类的细节实现,在主类的构造函数中,我们完成了实现类指针的实例化:



    // MyClass.cpp  
  • class MyClassImpl {  
    public:  
  • int foo() {  
    return bar();  
  • }  
    int bar() { return var++; }  
  • int var;  
    };  
  • MyClass::MyClass() : m_pImpl(new MyClassImpl){}  
    MyClass::~MyClass()  
  • {  
    try {  
  • delete m_pImpl;  
    }  
  • catch (...) {}  
    }  
  • int MyClass::foo(){ return m_pImpl->foo(); }

Pimpl机制其实这是桥接模式的一种变种。我们可以对实现类随意的进行增删和修改,而不会导致包含MyClass.h的源代码重新编译。当然,这样做的时间开销和空间开销也是有的。
在实践中,我们常常采用内部类来完成Pimpl机制:


    // header  
  • class fruit  
    {  
  • public:   
    private:  
  • class impl;  
    impl* pimpl_;  
  • }   
    // implementation  
  • class fruit::impl  
    {   
  • };   
    fruit::fruit()  
  • {  
    pimpl_ = new impl();  
  • }

希望看后本文,你会有收获。


您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表