模板參數
默認類型參數
函數參數可以設定一個默認值,我們現在可以對類模板的類型參數設定一個默認類型。
指定泛型Stack的默認類型參數為 int
template<typename T = int>
class Stack{...
};
當我們這樣定義一個對象時:
Stack<> stack;
使用默認的方式,或者說隱式的方式,實例化了一個stack對象。
這樣的好處是:指定默認類型之后,使用者就沒必要去寫了。
非類型參數
在模板前綴中使用非類型參數。
實例化模板時,非類型實參應該是對象。
如下:
template<typename T, int capacity>
class Stack {...
private:T elements[capacity];int size;
};
Stack<char, 100> charStack;
如同std里面的array的初始化:std::array<int,100>;
除了基本數據類型外,非類型實參是對象的時候是這樣的;
template<typename T, Color c>
class Label {...
};
Color color(0,0,255);
Label<char,color> label;
注意,參數默認值必須是在最右邊,當然我們也可以全部定義一個默認值,這樣就不會有問題了。
注意模板成員函數的聲明也需要進行修改。
就是這樣:
//泛型化
template <typename T = char,int N = 100>
//編寫StackOfIntegers類
class Stack {
private:T elements[N];int size{ 0 };
public:bool empty();T peek();T push(T value);T pop();int getSize();Stack();
};
template <typename T, int N>
Stack<T,N>::Stack() {size = 0;for (auto& i : elements) {i = 0;}
}
模板繼承
關于模板繼承的幾個原則:
1、普通類可從類模板實例繼承。一個模板實例化之后就是一個類了,類與類之間可以繼承。
2、模板可從普通類繼承
3、類模板可繼承類模板
也就是說,一個類是不可以從一個模板繼承的,其他的三種組合方式都是可以的。
何時何地使用模板
使用別人寫好的模板庫時
對不同類型的數據做類似處理 (算法、容器、遍歷等)
OOP or GP
泛型編程在C++中廣泛使用,經常可以取代面向對象編程。
幾乎整個C++標準庫都依賴于泛型編程。
在C++標準庫較少使用繼承和運行時多態。異常、字符串和IO流中使用了較多的繼承。