1類模板
1.1爲什麼需要類模板
類模板與函數模板的定義和使用類似,我們已經進行了介紹。 有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同,如下面語句聲明瞭一個類:
Ø 類模板用於實現類所需數據的類型參數化
Ø 類模板在表示如數組、表、圖等數據結構顯得特別重要,
這些數據結構的表示和算法不受所包含的元素類型的影響
1.2繼承中的類模板語法
//結論: 子類從模板類繼承的時候,需要讓編譯器知道 父類的數據類型具體是什麼(數據類型的本質:固定大小內存塊的別名)A<int> // class B : public A<int> { public: B(int i) : A<int>(i) {
} void printB() { cout<<"A:"<<t<<endl; } protected: private: };
//模板與上繼承 //怎麼樣從基類繼承 //若基類只有一個帶參數的構造函數,子類是如何啓動父類的構造函數 void pintBB(B &b) { b.printB(); } void printAA(A<int> &a) //類模板做函數參數 { // a.getT(); }
void main() { A<int> a(100); //模板了中如果使用了構造函數,則遵守以前的類的構造函數的調用規則 a.getT(); printAA(a);
B b(10); b.printB();
cout<<"hello..."<<endl; system("pause"); return ; } |
1.3類模板語法知識體系梳理
1.3.1所有的類模板函數寫在類的內部
所有類的成員函數或重載函數都在類的內部定義並實現。
1.3.2所有的類模板函數寫在類的外部,在一個cpp中
//構造函數 沒有問題
//普通函數 沒有問題
//友元函數:用友元函數重載 << >>
// friend ostream& operator<< <T> (ostream &out, Complex<T> &c3) ;
//友元函數:友元函數不是實現函數重載(非 << >>)
//1)需要在類前增加 類的前置聲明 函數的前置聲明
template<typename T>
class Complex;
template<typename T>
Complex<T> mySub(Complex<T> &c1, Complex<T> &c2);
//2)類的內部聲明 必須寫成:
friend Complex<T> mySub <T> (Complex<T> &c1, Complex<T> &c2);
//3)友元函數實現 必須寫成:
template<typename T>
Complex<T> mySub(Complex<T> &c1, Complex<T> &c2)
{
Complex<T> tmp(c1.a - c2.a, c1.b-c2.b);
return tmp;
}
//4)友元函數調用 必須寫成
Complex<int> c4 = mySub<int>(c1, c2);
cout<<c4;
結論:友元函數只用來進行 左移 友移操作符重載。
1.3.3所有的類模板函數寫在類的外部,在不同的.h和.cpp中,
也就是類模板函數說明和類模板實現分開
//類模板函數
構造函數
普通成員函數
友元函數
用友元函數重載<<>>;
用友元函數重載非<< >>
//要包含.cpp
1.3.4總結
歸納以上的介紹,可以這樣聲明和使用類模板:
1) 先寫出一個實際的類。由於其語義明確,含義清楚,一般不會出錯。
2) 將此類中準備改變的類型名(如int要改變爲float或char)改用一個自己指定的虛擬類型名(如上例中的numtype)。
3) 在類聲明前面加入一行,格式爲:
template <class 虛擬類型參數>
如:
template <class numtype> //注意本行末尾無分號
class Compare
{…}; //類體
4) 用類模板定義對象時用以下形式:
類模板名<實際類型名> 對象名;
類模板名<實際類型名> 對象名(實參表列);
如:
Compare<int> cmp;
Compare<int> cmp(3,7);
5) 如果在類模板外定義成員函數,應寫成類模板形式:
template <class 虛擬類型參數>
函數類型 類模板名<虛擬類型參數>::成員函數名(函數形參表列) {…}
關於類模板的幾點說明:
1) 類模板的類型參數可以有一個或多個,每個類型前面都必須加class,如:
template <class T1,class T2>
class someclass
{…};
在定義對象時分別代入實際的類型名,如:
someclass<int,double> obj;
2) 和使用類一樣,使用類模板時要注意其作用域,只能在其有效作用域內用它定義對象。
3) 模板可以有層次,一個類模板可以作爲基類,派生出派生模板類。
1.4類模板中的static關鍵字
Ø 從類模板實例化的每個模板類有自己的類模板數據成員,該模板類的所有對象共享一個static數據成員
Ø 和非模板類的static數據成員一樣,模板類的static數據成員也應該在文件範圍定義和初始化
Ø 每個模板類有自己的類模板的static數據成員副本
原理圖