最近又翻了一次 "Andrei Alexandrescu, Modern C++ Design",這次又有不同的感受,所謂的 Policy 編程技術,簡單的說就是 template + 多重繼承的技術。其中又有兩個關鍵名詞
Policy: 用來定義一個 Class 或 Class template 的介面
Hosts/Host Classes: 採用一個或多個 Policy,簡單的說就是 Policy 收納器
有這層基本概念後,我們可以利用這種技術,設計一個頗具彈性的程式,以下使用一個簡單的兩位數四則運算作為範例
/**
* Add Policy
*
*/
template< typename T>
struct AddCalc{
T Add(T a, T b){
return a+b;
}
};
/**
* Sub Policy
*
*/
template< typename T>
struct SubCalc{
T Sub(T a, T b){
return a-b;
}
};
/**
* Mul Policy
*
*/
template< typename T>
struct MulCalc{
T Mul(T a, T b){
return a*b;
}
};
/**
* Div Policy
*
*/
template< typename T>
struct DivCalc{
T Div(T a, T b){
return a/b;
}
};
/**
* Host Classes
*
*/
template<
typename T = int,
template<class> class AddPolicy = AddCalc,
template<class> class SubPolicy = SubCalc,
template<class> class MulPolicy = MulCalc,
template<class> class DivPolicy = DivCalc
>
class Calculator
: public AddPolicy<T>,
public SubPolicy<T>,
public MulPolicy<T>,
public DivPolicy<T>
{
public:
};
/**
* Add Policy
*
*/
template< typename T>
struct ErrorAddCalc{
T Add(T a, T b){
return a+b+100;
}
};
int main(int argc, char* argv[])
{
typedef Calculator<int> IntCalculator;
typedef Calculator<float> FloatCalculator;
std::cout << "IntCalculator:n";
IntCalculator ic;
std::cout << ic.Add(100, 200) << std::endl; // 300
std::cout << ic.Sub(100, 200) << std::endl; // -100
std::cout << ic.Mul(100, 200) << std::endl; // 20000
std::cout << ic.Div(100, 200) << std::endl << std::endl; // 0
std::cout << "FloatCalculator:n";
FloatCalculator fc;
std::cout << fc.Add(100, 200) << std::endl; // 300
std::cout << fc.Sub(100, 200) << std::endl; // -100
std::cout << fc.Mul(100, 200) << std::endl; // 20000
std::cout << fc.Div(100, 200) << std::endl << std::endl; // 0.5
// 透過自訂 AddPolicy 改變行為
typedef Calculator<int, ErrorAddCalc> ErrorCalculator;
std::cout << "ErrorCalculator:n";
ErrorCalculator ec;
std::cout << ec.Add(100, 200) << std::endl << std::endl; // 400
typedef Calculator<std::string> StringCalculator;
StringCalculator sc;
std::cout << sc.Add("Author: ", " Chui-Wen Chiu") << std::endl;
std::cout << sc.Add("Blog: ", " http://chuiwenchiu.spaces.live.com") << std::endl;
return 0;
}
從上述程式可發現,定義了一個如下的 Host Classes
template<
typename T = int,
template<class> class AddPolicy = AddCalc,
template<class> class SubPolicy = SubCalc,
template<class> class MulPolicy = MulCalc,
template<class> class DivPolicy = DivCalc
>
class Calculator
這就是剛剛說得 template + 多重繼承的寫法。
第一個參數表示,這個計算器要處理的元素型別,因此,可透過測試程式的 IntCalculator 和 FloatCalculator 發現,如果你熟悉 STL/boost 那對於這個參數的用途應該很熟悉。重點是接下來的四個 Policy 參數,主要用來決定 Calculator 的行為。四個 Policy 的用途如下:
Add Policy: 定義 Add 介面,回傳兩參數運算後的值
Sub Policy: 定義 Sub 介面,回傳兩參數運算後的值
Mul Policy: 定義 Mul 介面,回傳兩參數運算後的值
Div Policy: 定義 Div 介面,回傳兩參數運算後的值
因為這些 Policy 皆為 Calculator 的 template 參數,所以,可以自訂符合介面的 Policy,例如上述的 ErrorCalculator。
由上述的簡單範例你是否對 C++ Policy 編程有點瞭解了呢?
雖然看不懂但是覺得很有趣
高手就是不一样
非主流