【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) 其主要作用是解开类的使用接口和实现的耦合。
  • huangjh2017
  • huangjh2017
  • 2017年04月14日 15:44
  • 156

C++中的PImpl的技巧及其作用

1、PImpl(private implementation) 其主要作用是解开类的使用接口和实现的耦合。2、Pimpl 手法能比较完善的解决这些问题。利用 Pimpl 手法,我们把数据细节隐藏到一个...
  • DAo_1990
  • DAo_1990
  • 2015年09月02日 10:03
  • 958

编译防火墙——C++的Pimpl惯用法解析

Pimpl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法。这个技巧可以避免在头文件中暴露私有细节(见下图1),因此是促进A...
  • lihao21
  • lihao21
  • 2015年08月30日 19:55
  • 7838

C++的PIMPL模式解析

PIMPL(pointer to implementation)是一种常用的,用来对“类的接口与实现”进行解耦的方法。pimpl具有如下优点: 降低模块的耦合 降低编译依赖,提高编译速度 接口与实现...
  • janeqi1987
  • janeqi1987
  • 2017年06月29日 08:49
  • 198

c++中pimpl用法总结

在编写稳定代码是,管理好代码间的依赖性是不可hu
  • newyher
  • newyher
  • 2014年10月13日 16:30
  • 1157

C++ PIMPL模式

//x.h class X { public: void Fun(); private: int i; //add int i; }; //c.h #include class C...
  • xiongping_
  • xiongping_
  • 2016年02月25日 17:23
  • 307

pimpl idiom in c++

Introduction 在C++里面, 经常出现的情况就是头文件里面的类定义太庞大了,而这个类的成员变量涉及了很多 其他文件里面的类,从而导致了其他引用这个类的文件也依赖于这些成员变量的定义。...
  • wo17fang
  • wo17fang
  • 2014年05月08日 09:57
  • 710

PIMPL机制

总结:*PIMPL机制使类(目标类)的实现私用化,来降低编译依赖,提高重编译速度,保持类接口稳定性。 *PIMPL机制的实施方法是:在(类的头文件)声明目标类时,在类中添加私有成员:一个内部类(实现...
  • xiaoxiaoyusheng2012
  • xiaoxiaoyusheng2012
  • 2014年01月19日 23:50
  • 374

c++ PIMPL

PIMPL(Private Implementation 或 Pointer to Implementation)是通过一个私有的成员指针,将指针所指向的类的内部实现数据进行隐藏。      pIm...
  • swjtuwyp
  • swjtuwyp
  • 2016年05月24日 23:06
  • 448

C++之善用PIMPL技巧

PIMPL(Pointer to Implementation)这个手法可以解決/改善C++编码时常碰到的2大问题。 1.class增加private/protected成员时,使用此class的相...
  • caoshangpa
  • caoshangpa
  • 2017年11月21日 11:46
  • 78
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【C++程序设计技巧】Pimpl机制
举报原因:
原因补充:

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