PIMP(指针成员指向实现,接口与实现分离)和NVI(非虚拟接口,私有虚函数)都是为了将不变的代码控制,需要变化的部分单独用一个函数包裹起来,PIMPL使用的委托,不过NVI使用的继承而已。
从设计模式上来讲,PIMP使用的策略模式,NVI使用的则是模板模式。
下面的Dowork() 具体工作,在不同的继承类中细化,可以是变化的,不过控制代码是不变的,这样即使Dowork() 需要修改,Base类却不需要编译,基类拥有控制权.
虚函数是动态绑定的,所以只要不是在类外部调用虚函数,仅类内部调用虚函数无所谓访问控制,最终调用的都是派生类的虚函数。
class Base
{
public :
void Work(void)
{
... // <-此处可以加入控制代码
DoWork();
... // <-此处可以加入控制代码
}
private:
virtual void DoWork(void) = 0;
};
B即使需要修改,只要B的共有接口不变,pimpl总是个指针,对A 的布局不会发生影响,所以A自身不需要修改,使用A的类也不需要发生修改,也就不需要重新编译:
class A
{
public:
void func()
{
//此处加入不变的控制代码
pimpl->func();
//此处加入不变的控制代码
}
private:
B* pimpl;
};
这样降低了耦合,也实现了信息的隐藏。