在c++中。編譯器在看到模板的定義的時候。並不馬上產生**,僅僅有在看到用到模板時,比方呼叫了模板函式 或者 定義了類模板的
物件的時候。編譯器才產生特定型別的**。
一般而言,在呼叫函式的時候,僅僅須要知道函式的宣告就可以;
在定義類的物件時,僅僅須要知道類的定義,不須要成員函式的定義。
可是,這對於模板編譯是
不奏效的。模板要進行例項化,則必須可以訪問定義模板的原始碼。當呼叫函式模板以及類模板的成員函式
的時候,須要知道函式的定義
。
標準c++對於模板的編譯提供了兩種策略:
同樣之處:「將類定義以及函式宣告放在標頭檔案裡,而函式定義以及成員函式的定義放在原始檔裡」。
不同之處:編譯器如何使用來自原始檔的定義。
包括編譯模型
:
編譯器必須看到用到的全部的模板的定義。
一般能夠在宣告類模板以及函式模板的標頭檔案裡,加入include語句。指示該定義可用。即:
#include 「file.cc」 //file.cc是包括了相關函式實現的原始檔
長處:保證了原始檔與定義檔案的分離。
缺點:在不論什麼使用到該模板的原始檔裡,編譯時,編譯器都會為事實上例化乙份。也就意味著同乙個函式模板可能有多份例項化。在鏈結的時候。編譯器會選擇乙份例項化,扔掉其它的。
顯然,這整個過程是非常費時的。
分別編譯模型:
編譯器會跟蹤相關模板的定義,因此我們必須事先告訴編譯器。哪些模板是須要記住的。
使用exportkeyword能夠做到這一點。
每乙個模板僅僅能使用exportkeyword
一次!!
因此: 1 在函式模板的定義時指明該函式是可匯出的; 2 在類的實現檔案裡使用exportkeyword,(假設在類定義的檔案裡使用。那麼該標頭檔案僅僅能被某個原始檔包括一次!。)。
即:exporttemplatecompare (const t &, const t &) // 在函式的實現體指明export
exporttemplateclass myclass; // 在類的實現檔案裡使用export
注: 儘管有點多餘,可是還是說一下。類的定義檔案以及實現檔案,定義檔案是指定義類的成員變數(即屬性)的檔案。實現檔案是實現類的介面的檔案。
值得注意的是:
匯出類模板的成員自己主動為匯出的。
能夠指定類模板的個別成員是可匯出的,那麼那些不可匯出的成員必須遵循 包括編譯模型,即定義必須放在定義類模板的檔案裡。
編譯模板本身是非常複雜的工作。可是這對使用者而言是透明的,所有交給了編譯器來承擔,可是對於模板使用者來說,仍然有一些難點。
在模板中,包括兩種名字:依賴於模板形參的名字,以及不依賴於模板形參的名字。
對於模板的設計者來說,保證全部不依賴於模板形參的名字在模板本身的作用於中定義。
對於模板的使用者來說,保證與模板形參相關的函式、型別以及宣告等可見。
類模板內部的例項化機制:
在以下的類模板中。有:
template
class item
;
template
class queue
;
C 中的模板(類模板 模板類 模板函式)
1 class 一般class用於定義類,在模板引入c 後,最初定義模板的方法為 template,這裡class關鍵字表明t是乙個型別 2 typename 為了避免class在這兩個地方的使用可能給人帶來混淆,所以引入了typename這個關鍵字,它的作用同class一樣表明後面的符號為乙個型別...
C 模板函式和模板類的編譯與使用
對於模板,包括模板類與模板函式,它們的 其實並不是直接翻譯成二進位制 它要求有乙個 具體化 例項化 的過程,舉個例子 template void funa t t int main 也就是說,如果在main函式中,沒有呼叫過funa函式的話,那麼在main.obj中就找不到關於funa的任意二進位制...
類模板的分離編譯
一直覺得模板類是特別神奇的東西,它可以構造出不同型別的物件,使 更加的靈活。這個過程就是類模板的例項化。我們使用類的模板寫乙個stack類 include include seqlist1.h using namespace std templateclass container seqlist c...