Effective C++ 第三十五条 Consider alternative to virtual functions.

考虑 virtual 函数以外的其他选择
当我们在写 C++ 代码(尤其关于类)的时候,考虑继承体系的情况下,难以避免的会使用到 virtual 函数,然而我们有其他的办法来替代。
这里 derived 可以考虑重载 fun ,也可以不重载而使用 base::fun ,现在提供其他的选择。
Non-virtual Interface 实现 Template Method 模式
通过 public 下的 non-virtual 函数调用 private virtual 函数
在这里我们把 fun 称作 fun 的外覆器(wrapper),这样做的好处是我们可以在调用实际功能(_fun)之前准备好环境,调用完之后恢复环境。学过 库打桩 的就知道这其中的意义。比如我们可以在 _fun 之前上锁,然后解锁。
Function Pointer 实现 Strategy 模式
通过传入函数指针,来实现功能
这样做的好处是,我们可以通过在 base 外部写 fun,传入 base 从而实现 base 的不同功能,也可以留出一个接口 setFun 随时修改 base 的 fun 功能,但是也有一个点要考虑,就是外部函数不能调用 base 的 private 成员。这也是此方法的一大缺陷,你必须降低 base 的封装性来达到目的。优点就是每一个对象都可以有属于自己的功能函数。
std::function 完成 Strategy 模式
此方法和 Function Pointer 很类似,但是使用的不是 function pointer 而是 function object。
这里不同于 function pointer 的点在于,在本例子中 function pointer 的实例化是 void defaultF(void).接收类型是 void ,返回类型是 void。假设有一个函数指针 pF 参数类型是 int,返回是 double,那么这个指针只能接收 参数类型是int而且返回类型是 double 的函数,无法接收其他函数。如果是采用 std::function 的话,哪怕要求传入的是 double (int) ,你传入 int (double) 也是没关系的,因为会编译器会将参数类型隐式转换为你设定的参数类型,输出类型也隐式转换为你设定的输出类型。
古典的 Strategy 模式
此方式和 Function Pointer 、std::function 接近,只是传入的对象是类。
这种方式特别容易分辨,如果你想添加新的功能,只需要添加一个 baseTool 的子类即可完成。