码迷,mamicode.com
首页 > 编程语言 > 详细

C++的PIMPL模式解析

时间:2015-08-13 15:46:36      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:c++   pimpl   接口与实现   编译依赖   编译防火墙   

PIMPL(pointer to implementation)是一种常用的,用来对“类的接口与实现”进行解耦的方法。pimpl具有如下优点:

  • 降低模块的耦合
  • 降低编译依赖,提高编译速度
  • 接口与实现分离

为了实现pimpl模式,我们先来看一种普通的类的设计方法。
假如我们要设计一书籍类Book,Book包含目录属性,并提供打印书籍信息的对外接口,Book设计如下:

class Book
{
public:
  void print();
private:
  std::string  m_Contents;
}

Book的使用者只需要知道print()接口,便可以使用Book类,看起来一切都很美好。
然而,当某一天,发现Book需要增加一标题属性,对Book类的修改如下:

class Book
{
public:
  void print();
private:
  std::string  m_Contents;
  std::string  m_Title;
}

虽然使用print()接口仍然可以直接输出书籍的信息,但是Book类的使用者却不得不重新编译所有包含Book类头文件的代码。
为了隐藏Book类的实现细节,实现接口与实现的真正分离,可以使用pimpl模式。

/* public.h */

class Book
{
public:
  Book();
  ~Book();
  void print();
private:
  class BookImpl;
  BookImpl* m_p;
};

为简单实现起见,Book类省略了拷贝构造函数和拷贝赋值函数。在实际应用中,应该对这两个函数进行定义。
在对外的头文件public.h中,只包含Book类的外部接口,将真正的实现细节被封装到BookImpl类。为了不对外暴露BookImpl类,将其声明为Book类的内嵌类,并声明为private。
BookImpl类的头文件如下。

/* private.h */

#include "public.h"
#include <iostream>

class Book::BookImpl
{
public:
  void print();

private:
  std::string  m_Contents;
  std::string  m_Title;
};

private.h并不需要提供给Book类的使用者,因此,如果往后需要重新设计书籍类的属性,外界对此一无所知,从而保持接口的不变性,并减少了头文件之间的依赖关系。

/* book.cpp */

#include "private.h"
#include "public.h"

Book::Book()
{
  m_p = new BookImpl();
}

Book::~Book()
{
  delete m_p;
}

void Book::print()
{
  m_p->print();
}

/* then BookImpl functions */

void Book::BookImpl::print()
{
  std::cout << "print from BookImpl" << std::endl;
}

使用Book类的接口的方法如下:

/* main.cpp */

#include "public.h"

int main()
{
    Book book;
    book.print();

    return 0;
}

可以使用下图来说明pimpl模式在以上Book类设计的作用:
技术分享
pimpl也因此常被称为“编译器防火墙“ 。

参考资料

  1. C++ Programming/Idioms: Pointer To Implementation (pImpl)
  2. The C++ Pimpl
  3. Compilation Firewalls
  4. PIMPL模式

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++的PIMPL模式解析

标签:c++   pimpl   接口与实现   编译依赖   编译防火墙   

原文地址:http://blog.csdn.net/lihao21/article/details/47610309

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!