【C++程序设计技巧】Pimpl机制

转载 2016年06月01日 14:39:09
作者:gnuhpc 

出处:http://www.cnblogs.com/gnuhpc/

1.简介

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

2.机制分析

首先,我们先看看不使用这个机制的一个实现:

  1: // MyBase.h
  2: class MyBase {
  3: public:
  4:   int foo();
  5: };
  6: 
  7: // MyDerived.h
  8: #include "MyBase.h"
  9: class MyDerived : public MyBase {
 10: public:
 11:   int bar();
 12: };

假设你现在希望在MyBase.h中加入一个新的private和protected成员函数,那么MyDerived和所有包含MyBase.h的源文件都需要重新编译。在一个大工程中,这样的修改可能导致重新编译时间的激增。你可以使用Doxygen或者SciTools看看头文件依赖。

一般来说,不在头文件中包含头文件是一个比较好的习惯,但是这也不能完全消除修改MyBase.h带来的重新编译代价。有没有一个机制可以使得对私有接口做修改时我们可以减小重新编译的代价。

在Pimpl机制中,我们使用前置声明一个Impl类,并将这个类的一个指针实例放入主类中,如下:

  1: // MyClass.h
  2: class MyClassImpl;    // forward declaration
  3: class MyClass {
  4: public:
  5:   MyClass();
  6: ~MyClass();
  7:   int foo();
  8: private:
  9:   MyClassImpl *m_pImpl;
 10: };

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

 

  1: // MyClass.cpp
  2: class MyClassImpl {
  3: public:
  4: int foo() {
  5:         return bar();
  6: }
  7: int bar() { return var++; }
  8:         int var;
  9: };
 10: 
 11: MyClass::MyClass() : m_pImpl(new MyClassImpl){}
 12: 
 13: MyClass::~MyClass()
 14: {
 15:     try {
 16:             delete m_pImpl;
 17:     }
 18:     catch (...) {}
 19: }
 20: 
 21: int MyClass::foo(){ return m_pImpl->foo(); }

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

在实践中,我们常常采用内部类来完成Pimpl机制:

  1: // header
  2: class fruit
  3: {
  4: public: 
  5: 
  6: private:
  7: class impl;
  8: impl* pimpl_;
  9: } 
 10: 
 11: // implementation
 12: class fruit::impl
 13: { 
 14: 
 15: }; 
 16: 
 17: fruit::fruit()
 18: {
 19: pimpl_ = new impl();
 20: }

相关文章推荐

C++程序设计机制——Pimpl机制

PImpl(private implementation) 其主要作用是解开类的使用接口和实现的耦合。

C++程序的设计机制2 Pimpl机制

  • 2013年01月22日 10:01
  • 23KB
  • 下载

C++程序的设计机制2:Pimpl机制

1.简介这个机制是Private Implementation的缩写,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们一般都会修改私有接口,但是这会导致包含该头文件的所有源文件都要重新编译...

蓝桥杯C_C++/Java程序设计常用算法&技巧总结

蓝桥杯C_C++/Java程序设计常用算法&技巧总结

C++编程实用技巧——专家讲述C++程序设计的窍门

从C转向C++ 对每个人来说,习惯C++需要一些时间,对于已经熟悉C的程序员来说,这个过程尤其令人苦恼。因为C是C++的子集,所有的C的技术都可以继续使用,但很多用起来又不太合适。例如,C++程...

海量数据处理程序设计技巧(附C++代码)

已移到:http://www.wypblog.com/archives/158求解问题如下:在本地磁盘里面有file1和file2两个文件,每一个文件包含500万条随机整数(可以重复),最大不超过21...

Visual C++的程序设计技巧

Microsoft Visual C++是一种可视化编程语言,因功能强大而受到广大程序设计人员的青睐。但是,由于VC++的应用程序框架结构非常复杂,使得许多初学者望而却步。本文通过对设置视图背景颜色...

【C++程序设计技巧】NVI(Non-Virtual Interface )

在C++的程序设计中有一些设计开发的典型技巧需要整理讨论,在此抛砖引玉,为自己做积累,请高人也多多指教。 1.简介 在标准C++库中我们可以看到这样的一个现象: 6个公有虚函数,并且都是std:...

Visual C++6.0 程序设计从入门到精通(三) - MFC的消息机制

1. 引言MFC 系统,乃至Windows 系统,是一个以消息为核心的系统,它将系统中发生的事件看做一个消息,放置在消息队列中,待系统在合适的时机进行处理。因此,理解 MFC 系统的消息机制显得十分重...

Visual C++6.0 程序设计从入门到精通(二) - MFC应用程序的启动和运行机制

1. 全局对象theappMFC 应用程序的启动和运行依赖于应用程序类对象,这个类对象在程序中只能有一个,且是全局的。2. 应用程序类对象的数据成员CWinApp 所包含的数据成员主要用于存放和控制应...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【C++程序设计技巧】Pimpl机制
举报原因:
原因补充:

(最多只允许输入30个字)