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

考慮 virtual 函數(shù)以外的其他選擇
當我們在寫 C++ 代碼(尤其關于類)的時候,考慮繼承體系的情況下,難以避免的會使用到 virtual 函數(shù),然而我們有其他的辦法來替代。
這里 derived 可以考慮重載 fun ,也可以不重載而使用 base::fun ,現(xiàn)在提供其他的選擇。
Non-virtual Interface 實現(xiàn) Template Method 模式
通過 public 下的 non-virtual 函數(shù)調(diào)用 private virtual 函數(shù)
在這里我們把 fun 稱作 fun 的外覆器(wrapper),這樣做的好處是我們可以在調(diào)用實際功能(_fun)之前準備好環(huán)境,調(diào)用完之后恢復環(huán)境。學過 庫打樁 的就知道這其中的意義。比如我們可以在 _fun 之前上鎖,然后解鎖。
Function Pointer 實現(xiàn) Strategy 模式
通過傳入函數(shù)指針,來實現(xiàn)功能
這樣做的好處是,我們可以通過在 base 外部寫 fun,傳入 base 從而實現(xiàn) base 的不同功能,也可以留出一個接口 setFun 隨時修改 base 的 fun 功能,但是也有一個點要考慮,就是外部函數(shù)不能調(diào)用 base 的 private 成員。這也是此方法的一大缺陷,你必須降低 base 的封裝性來達到目的。優(yōu)點就是每一個對象都可以有屬于自己的功能函數(shù)。
std::function 完成 Strategy 模式
此方法和 Function Pointer 很類似,但是使用的不是 function pointer 而是 function object。
這里不同于 function pointer 的點在于,在本例子中 function pointer 的實例化是 void defaultF(void).接收類型是 void ,返回類型是 void。假設有一個函數(shù)指針 pF 參數(shù)類型是 int,返回是 double,那么這個指針只能接收 參數(shù)類型是int而且返回類型是 double 的函數(shù),無法接收其他函數(shù)。如果是采用 std::function 的話,哪怕要求傳入的是 double (int) ,你傳入 int (double) 也是沒關系的,因為會編譯器會將參數(shù)類型隱式轉(zhuǎn)換為你設定的參數(shù)類型,輸出類型也隱式轉(zhuǎn)換為你設定的輸出類型。
古典的 Strategy 模式
此方式和 Function Pointer 、std::function 接近,只是傳入的對象是類。
這種方式特別容易分辨,如果你想添加新的功能,只需要添加一個 baseTool 的子類即可完成。