1. 什么是PIMPL?
1.Private Implementation
直接的字面意思就是“实现私有化”,也如我们常常听到诸如“不要改动你的公有接口”这样的建议,Pimpl机制,顾名思义,将实现私有化,力图使得头文件对改变不透明。主要作用是解开类的使用接口和实现的耦合。
2.pointer to implementation
这种说法语义上更关注代码的实现方法,也就是一个指向实现的指针。
3.桥接模式
其实,这也是一个简单的桥接模式.
2. 实例
// file y.h
#include "x.h“
class Y
{
void Fun();
X x_;
};
// file y.cpp
#include “y.h”
void Y::Fun
{
return x_.Fun();
}
// file main.cpp
#include “y.h”
int main(void)
{
Y y;
y.Fun();
}
上面程序存在的问题是:
1、引入更多的头文件,降低编译速度
2、在编译期如果X的大小改变了,y.cpp 和 main.cpp 都得重新编译;在运行期,如果X有子类,也不能使用多态虚函数。
3、假设y.cpp 编译成动态库给main.cpp 使用,当X的大小变化,动态库需要重新编译,此时main.cpp 因为有定义对象y ,故也需要
重新编译。
下面介绍一种PIMPL 技法,有人也把它当作一种设计模式:
PIMPL(private implementation或pointer to implementation)也称为handle/body idiom
PIMPL背后的思想是把客户与所有关于类的私有部分的知识隔离开。避免其它类知道其内部结构
降低编译依赖、提高重编译速度
接口和实现分离
降低模块的耦合度
编译期
运行期
提高了接口的稳定程度
改进后的程序代码为:对于库的使用,方法不能改变
对于库的编译,动态库的变更,客户程序不用重新编译
// file y.h
class X;
class Y
{
Y();
~Y();
void Fun();
X *px_;
};
// file y.cpp
#include "x.h"
Y::Y() : px_( new X ) {}
Y::~Y()
{
delete px_;
px_ = 0;
}
void Y::Fun()
{
return px_->Fun();
}
// file main.cpp
#include “y.h”
int main(void)
{
Y y;
y.Fun();
}
即Y 内部成员是X* 指针,在32位系统上,指针大小固定为4个字节,即使X大小改变,也不影响Y。如果X 有子类,通过基类指针px_
还可以实现虚函数多态。