c++中有乙個重要特性,那就是模板型別。類似於objective-c中的泛型,c++通過類模板來實現泛型支援。它使用引數化的型別建立相應的函式和類,分別稱之為函式模板和類模板。
模板是一種對型別進行引數化的工具,通常有兩種形式:函式模板和類模板。函式模板針對僅引數型別不同的函式;類模板針對僅資料成員和成員函式型別不同的類,可以顯著減小源**的大小並提高**的靈活性,而不會降低型別安全。
模板(有時稱為參模板(有時稱為引數化型別)是用於生成基於型別引數的函式和類的機制。通過使用模板,可以設計操作多種型別的資料的單個類或函式,而不必為每種型別建立單獨的函式或類。
使用模板有很多原因,最主要的為了得到通用程式設計的優點。國際標準化組織(iso)為c++建立了c++標準庫,該標準庫功能強大,這證明了模板的重要性。庫中涉及演算法和容器的部分組成了標準模板庫(簡稱stl)。由於模板的可重用性和可擴充套件性,你可以利用stl來實現效率很高的**。
但是模板也有一些不太為人知的缺點。首先,由於c++沒有二進位制實時擴充套件性,所以模板不能像庫那樣被廣泛使用。模板的資料型別只能在編譯時才能被確定。因此,所有用基於模板演算法的實現必須包含在整個設計的標頭檔案中。通過分析標準模板庫(stl)的標頭檔案,你可以很清楚的認識到這一點。
另外,由於模板只是最近加入c++標準中,所以有些c++編譯器還不支援模板,當使用這些編譯器時編譯含有模板的**時就會發生不相容問題。例如,mozilla瀏覽器開發組之所以沒有使用模板就是因為交叉平台會導致模板的不相容。同樣的,如果當開發者需要跨越好幾個平台而有的平台可能只有老的c++編譯器的時候,使用模板也是不明智的。
即使到現在,模板的一些高階特性,例如區域性特殊化和特殊化順序在不同的c++標準實現中也還是不統一的。
儘管如此,結合stl使用模板還是可以大大減少開發時間。模板可以把用同乙個演算法去適用於不同型別資料,在編譯時確定具體的資料型別。
乙個類模板(類生成類)允許使用者為類定義個一種模式,使得類中的某些資料成員、預設成員函式的引數,某些成員函式的返回值,能夠取任意型別(包括系統預定義的和使用者自定義的)。
如果乙個類中的資料成員的資料型別不能確定,或者是某個成員函式的引數或返回值的型別不能確定,就可以將此類宣告為模板,它的存在不是代表乙個具體的、實際的類,而是代表一類 類。
類模板以下面的這樣的**開頭
template
<
class
t>
關鍵字template或class告訴編譯器。將要定義乙個模板,尖括號的內容相當於函式的引數列表。可以把關鍵字template或class看做是變數的型別名該變數接受型別作為其值,把t看做變數的名稱。
如下,宣告乙個普通的類模板:
#include
using
namespace std;
template
<
typename t>
class
complex
//運算子過載
complex
operator
+(complex& c)
private
: t a;
t b;};
intmain()
模板除了定義型別引數,還可以在模板定義非型別引數
什麼是非型別形參?顧名思義,就是表示乙個固定型別的常量而不是乙個型別。通常來說,模板都是用作型別的泛化,而非型別引數則不同於以往的用處。
//示例**:
template
<
classt,
int maxsize>
class
list
}void
print()
}};
對應的非型別實參也有限制::
實參必須是編譯時常量表示式,不能使用非const的區域性變數,區域性物件位址及動態物件
非const的全域性指標,全域性物件,全域性變數(下面可能有個特例)都不是常量表示式。
由於形參的已經做了限定,字串,浮點型即使是常量表示式也不可以作為非型別實參。
非型別形參是有條件限制的:
浮點數不可以作為非型別形參,包括float,double。具體原因可能是歷史因素,也許未來c++會支援浮點數。
類不可以作為非型別形參。
字串不可以作為非型別形參。
整形,可轉化為整形的型別都可以作為形參,比如int,char,long,unsigned,bool,short(enum宣告的內部資料可以作為實參傳遞給int,但是一般不能當形參)
指向物件或函式的指標與引用(左值引用)可以作為形參。
非型別模版引數作用:
模板定義內,非型別模板引數是乙個常量值,所以,在需要常量表示式的地方,可以使用這個特性,例如,指定陣列大小(例如上面示例**中指定最大size)
可以作為乙個引數傳入的方式,只是這個引數有上述的一些性質。
模版類的定義和實現不能分開寫在不同檔案中,否則會導致編譯錯誤
原因:在c++中,在編譯階段才確定物件所占用的空間。模板類只有被真正使用的時候,編譯器才知道,模板套用的是什麼型別,應該分配多少空間。然後根據套用的型別進行編譯。套用不同型別的模板類實際上就是兩個不同的型別,因此這兩個型別的共同成員函式實質上也不是同乙個函式,僅僅是具有相似的功能。因此,模板類在套用不同型別以後,會被編譯出不同的**。
結論:
1.模板類本身未指定所使用的資料型別,不能單獨編譯模板類的實現。 只用在使用模板類的階段,指定了模板中的資料型別,編譯器才能正常編譯。因此,在實際開發中,必須把實現全部寫在標頭檔案裡面,把宣告和實現分開的做法不可取。
2.模版不支援在區域性函式中宣告定義或使用
3…使用模板時,template宣告行同使用t的函式之間不允許出現其它**。
4.自動型別推導,必須推導出一致的資料型別t,才可以使用模板必須要確定出t的資料型別,才可以使用。
C 函式模板詳解及注意事項
c 語言引入模板技術,它使用引數化的型別建立相應的函式和類,分別稱之為函式模板和類模板,本章介紹函式模板 函式模板 可以用來建立乙個通用功能的函式,以支援多種不同形參,進一步簡化過載函式的函式體設計 意義 對於功能完全一樣,只是引數型別不同的函式,能寫一段通用 是用於多種不同的資料型別,會使 的可重...
模板類編寫注意事項
模版類的定義和實現不能分開寫在不同檔案中,否則會導致編譯錯誤 原因 在c 中,在編譯階段才確定物件所占用的空間。模板類只有被真正使用的時候,編譯器才知道,模板套用的是什麼型別,應該分配多少空間。然後根據套用的型別進行編譯。套用不同型別的模板類實際上就是兩個不同的型別,因此這兩個型別的共同成員函式實質...
C 模板使用注意事項
c 模板使用有很多的規則,如果稍有問題便會出問題。由於c 宣告模板和實現模板規則不一樣,很容易出錯,現將遇到的注意事項列出來,當便大家也方便自己以後找錯。1 類的內部區域性模板成員函式不能是虛擬的,virtual這個識別符號。2 宣告了模板類,在實現其介面的時候注意在類網域名稱加上 類名 定義的泛型...