1、借由 Non-Virtual Interface(NVI) 手法实现 Template Method 模式

       NVI手法将虚函数作为private的,然后用非虚函数作为接口来调用这个虚函数。这样就把虚函数封装起来了。

如:

//令客户通过调用public的非虚函数间接地调用private的虚函数。

class Widget
{
public:
        //这种作为虚函数与外界的交接的函数,被Scott Meyers称为virtual函数的外覆器(wrapper)
       void Draw() //派生类不重新定义这个函数
	{
            ... // Do something...
           DoDraw();
            ... // Do something...
	}
private:
	virtual void DoDraw() //派生类可以重新定义这个函数
	{
		...... //缺省的内容
	}
};

       另外,加上private的虚函数的一个测试:

// Rule35:考虑virtual函数以外的其他选择
#include <iostream>
#include <string>

using namespace std;

class B
{
private:
	virtual void DoShow()
	{
		cout << "I'm a Base." << endl;
	}
public:
	void Show()
	{
		DoShow();
	}
};

class D : public B
{
private:
	virtual void DoShow()
	{
		cout << "I'm a Derive." << endl;
	}
};

int main()
{
	D d;
	d.Show();

	B* p = new D;
	p->Show();
	
	B b;
	b.Show();

	return 0;
}
运行结果:


对于上述结果,《Effective C++》上有这样的解释:“重新定义函数”表示解释某些事“怎么”完成,而“调用函数”则表示它“何时”被完成。

这些事都是各自独立互不相干的。因此私有的virtual函数可以在子类中被重写,而不可以在子类中被调用。

2、借由 Function Pointers 实现Strategy模式