我們在編寫不同型別的引數的類時,特別是對於容器類,除了想儲存的物件型別不同外,**都相同,這時候我們希望一種泛型的類,我們可以將具體的型別用引數的形式傳遞給它,而不用每次都去實現。
c++的類模板為生成通用的類宣告提供了一種很好的方法。這也是**重用的重要的一部分。
首先怎樣定義乙個模板類:
template
關鍵字template 是告訴編譯器,將定義乙個模板。尖括號內容相當於是引數列表,關鍵字class 看做是變數的型別名,type是變數的名稱。
當然了使用class並不意味著只能用類做引數,這只是表明type是乙個通用的型別說明符,在模板的例項化是將使用具體的型別替代它,我們也可以使用typename 來代替class
template
template class stack;
template //每個函式頭都將以模板宣告開始
stack::stack()
template bool stack::push(const type & item)
重要的乙個概念就是:
模板不是類,也不是成員函式。它們只是c++編譯器指令,說明了如何生成類和成員函式。模板的具體實現是由例項化和具體化 來完成的。
我們一般將模板資訊放入標頭檔案中,在使用的時候包含標頭檔案。
接下來就是如何使用模板類,我們需要宣告乙個型別為模板類的物件,方法使用具體的型別作為引數。
比如,stackst; stackst2;
使用int 來替換type ,double 來替換type。
注意我們賦給型別引數的只能是型別,不能是數字。必須顯示的提供所需的型別。
模板類擴充套件:
1,模板中非型別引數的使用
template
關鍵字class指出t為型別引數,int 指出n的型別為int ,這種引數稱為非型別引數(表示式引數)。
表示式引數有一些限制:表示式引數可以是整型,列舉,引用,指標。模板**不可以修改引數的值,也不能使用引數的位址。比如n++ ,&n等。
2,模板的多功能性
遞迴使用模板:對於陣列模板array,可以array< array, 10> twodee;
這樣我們就得到乙個包含10個元素的陣列,每個元素都是包含5個int 元素的陣列。
模板可以包含多個型別引數:template ;
預設型別引數模板:template class topo;
如果我們例項化的時候省略t2,編譯器將使用int。
模板的具體化:
具體化可以分為隱式例項化,顯示例項化,顯示具體化,部分具體化。
1,隱式例項化
指出所需型別,宣告乙個或多個物件,主要用途是建立物件。
pt = new array;
編譯器生成類定義,然後根據定義建立乙個物件。
2,顯示例項化
使用關鍵字template 並指出所需型別來宣告類。
template class array;
沒有建立物件,只是生成類宣告。
3,顯示具體化
它是針對特定型別的定義。具有具體定義的模板,不同於泛型定義模板
template <> class array(const char *) ;
這是乙個專供char * 型別使用的模板。
在例項化時遵循乙個原則:當具體化模板和通用模板與例項化匹配時,編譯器優先使用具體化模板。
4,部分具體化
給型別引數的其中之一指定具體型別
template class pair;
關鍵字template 後面的<>宣告裡是沒有被具體化的型別引數,如果為空,表示顯示具體化、
template <> class pair;
如果有多個模板可供選擇,編譯器將使用具體化程度最高的模板。
模板的使用場景:
1,模板做為成員
template class bete
void show() const
};hold q;
hold n;
public:
beta(t t,int i):q(t),n(i){}
...};
這是beta模板中宣告和定義hold方法,q成員是基於型別t的hold物件。
如果在beta模板中宣告hold方法,在外面定義它,就會出現模板巢狀。
tempate class bete;
template template class bete::hold;
2,模板作為引數
模板可以包含本身就是模板的引數。
template class thing>
class crab
void reprots(hasfriend & hf) {}
report()並不是模板函式,只是使用乙個模板類引數,定義的時候,需要傳遞給它具體的型別。上面定義的兩個report()函式,分別是兩個特定hasfriend具體化的友元。
2,模板類的約束模板友元函式
友元函式成為模板,友元型別取決於類被例項化的型別。
template void couts();
template void reports(t &); // 第一步,宣告模板函式
template
class hasfriend{
friend void couts(); //第二步,將模板宣告為友元
friend void reports<> (hasfriend&);
template //第三步,提供模板定義
void couts{
cout << ... << endl;
couts()函式沒有引數,因此要使用<>來指明具體化型別,reports()函式有引數,可以從引數推斷出模板型別引數,所以<>可以為空。
在使用的時候,couts(),couts(),
hasfriendhf1;
hasfrinedhf2;
reports(hf1); //根據函式引數型別
reports(hf2);
3,非約束模板友元函式
在類內部宣告模板,每個函式具體化都是每個類具體化的友元。
tempalet
class many{
template friend void show(c & ,d &);
template void show(c & c,d & d){
cout << .. << endl;
show()函式是所有具體化的友元。
所有這些機制,都是為了讓我們能夠重用經過測試的**。
類模板和模板類
c 提供的函式模板可以定義乙個對任何型別變數進行操作的函式,從而大大增強了函式設計的通用性。使用函式模板的方法是先說明函式模板,然後例項化成相應的模板函式進行呼叫執行。函式模板的一般說明形式如下 template 模板形參表 返回值型別 函式名 模板函式形參表 其中,模板形參表 可以包含基本資料型別...
類模板和模板類
所謂類模板,實際上是建立乙個通用類,其資料成員 成員函式的返回值型別和形參型別不具體指定,用乙個虛擬的型別來代表。使用類模板定義物件時,系統會實參的型別來取代類模板中虛擬型別從而實現了不同類的功能。定義乙個類模板與定義函式模板的格式類似,必須以關鍵字template開始,後面是尖括號括起來的模板引數...
類模板的使用 類模板使用總結
歸納以上的介紹,可以這樣宣告和使用類模板 先寫出乙個實際的類。將此類中準備改變的型別名 如int要改變為float或char 改用乙個自己指定的虛擬型別名 如上例中的t 在類宣告前面加入一行,格式為 templatetemplate class a 類體用類模板定義物件時用以下形式 類模板名 實際型...