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

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.简介 这个机制是Private Implementation的缩写,我们常常听到诸如“不要改动你的公有接口”这样的建议,所以我们一般都会修改私有接口,但是这会导致包含该头文件的所有源文件都要重新编译,这会是个麻烦事儿。

作者: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: }


               作者:gnuhpc
               出处:http://www.cnblogs.com/gnuhpc/
               除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


分享到:

目录
相关文章
|
1月前
|
存储 安全 编译器
【c++】深入理解别名机制--引用
本文介绍了C++中的引用概念及其定义、特性、实用性和与指针的区别。引用是C++中的一种别名机制,通过引用可以实现类似于指针的功能,但更安全、简洁。文章详细解释了引用的定义方式、引用传参和返回值的应用场景,以及常引用的使用方法。最后,对比了引用和指针的异同,强调了引用在编程中的重要性和优势。
36 1
|
2月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
65 6
|
2月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化1
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
67 7
|
7月前
|
安全 C++
C++中的异常处理与错误处理机制
C++中的异常处理与错误处理机制
81 0
|
6月前
|
C++
C++ : 程序设计简单实例
C++ : 程序设计简单实例
47 3
|
6月前
|
安全 C++
C++:程序设计实例
C++:程序设计实例
54 2
|
6月前
|
C++
C++程序设计实践一上(题目来自杭州电子科技大学ACM)
C++程序设计实践一上(题目来自杭州电子科技大学ACM)
38 2
|
6月前
|
C++
C++程序设计实践一下(题目来自杭州电子科技大学ACM)
C++程序设计实践一下(题目来自杭州电子科技大学ACM)
45 1
|
6月前
|
存储 JavaScript 前端开发
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
|
6月前
|
C++
技术经验分享:C++程序设计的技巧
技术经验分享:C++程序设计的技巧
39 0