跳至主要內容

Pimpl

张威大约 2 分钟c/c++设计模式

Pimpl

PIMPL(Private Implementation 或Pointer to Implementation)是通过一个,将指针所指向的类的内部。PIMPL又称作“编译防火墙”,它的实现中就用到了嵌套类。PIMPL设计模式有如下优点:

  1. 提高编译速度;

    • 数据成员只有一个指针,使得每个对象占用内存较小
    • 可以将实现文件编译成库文件
  2. 实现信息隐藏;

    • 头文件只有接口和一个数据指针,无法推断出底层的实现
  3. 减小编译依赖,可以用最小的代价平滑的升级库文件;

    • 不需要重新编译就可以替换库文件,便于软件升级

      如果用户代码需要使用这个类,它就需要 include 这个头文件,根据 C++ 的头文件展开原则,其他的代码也需要 include 这个头文件里面涉及到的所有的头文件。因此,一旦这里面相关的代码有变动,不止变动的代码需要重新编译,用户代码也需要重新编译,这会使编译速度变得很慢。

  4. 接口与实现进行解耦;

  5. 移动语义友好。

//Line.h
class Line
{
public:
    Line(int,int,int,int);
    ~Line();
    void printLine() const;
private:
    class LineImpl;//类的前向声明   
    LineImple *_pimpl;
};
//Line.cc
#include "Line.h"

//功能实现由嵌套类实现
class Line::LineImpl
{
public:
    LineImpl(int x1, int y1, int x2, int y2);
    void printLineImpl() const;
private:
    class Point 
    {
    public:
        Point(int x = 0, int y = 0)
        : _x(x), _y(y)
        {
            
        }
        
        void print() const;
    private:
        int _x;
        int _y;
    };
    
    Point _pt1;
    Point _pt2;    
};

Line::LineImpl::LineImpl(int x1, int y1, int x2, int y2)
: _pt1(x1, y1)
, _pt2(x2, y2)
{
}

void Line::LineImpl::printLineImpl() const
{
    _pt1.print();
    cout << " ---> ";
    _pt2.print();
    cout << endl; 
}

//外部接口
Line::Line(int x1, int y1, int x2, int y2)
: _pimpl(new LineImpl(x1, y1, x2, y2))
{
    
}

Line::~Line() 
{   
    delete _pimpl; 
    _pimpl = nullpter;
}

void Line::printLine() const
{
    _pimpl->printLineImpl();
}