C 模板的申明和定義

2021-07-05 01:12:44 字數 1129 閱讀 5161

template class cqtree

;template cqtree::cqtree()

template cqtree::~cqtree()

最近寫**,需要用到模板,果斷將模板的申明和定義分別寫到了.h和.cpp檔案中,後來程式總是編譯出錯。後來查詢原因,發現c++中模板和定義的實現最好寫在同一.h檔案中,其實以前就遇到過,好久沒用了,居然忘記了,因此特此記錄一番。

原因如下:

「通常情況下,你會在.h檔案中宣告函式和類,而將它們的定義放置在乙個單獨的.cpp檔案中。但是在使用模板時,這種習慣性做法將變得不再有用,因為當例項化乙個模板時,編譯器必須看到模板確切的定義,而不僅僅是它的宣告。因此,最好的辦法就是將模板的宣告和定義都放置在同乙個.h檔案中。這就是為什麼所有的stl標頭檔案都包含模板定義的原因。」[1]

"標準要求編譯器在例項化模板時必須在上下文中可以檢視到其定義實體;而反過來,在看到例項化模板之前,編譯器對模板的定義體是不處理的——原因很簡單,編譯器怎麼會預先知道 typename 實參是什麼呢?因此模板的例項化與定義體必須放到同一翻譯單元中。"[1]

"《c++程式設計思想》第15章(第300頁)說明了原因:

模板定義很特殊。由template<…> 處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被乙個模板例項告知。在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。"[2]

"對c++編譯器而言,當呼叫函式的時候,編譯器只需要看到函式的宣告。當定義類型別的物件時,編譯器只需要知道類的定義,而不需要知道類的實現**。因此,因該將類的定義和函式宣告放在標頭檔案中,而普通函式和類成員函式的定義放在原始檔中。

但在處理模板函式和類模板時,問題發生了變化。要進行例項化模板函式和類模板,要求編譯器在例項化模板時必須在上下文中可以檢視到其定義實體;而反過來,在看到例項化模板之前,編譯器對模板的定義體是不處理的——原因很簡單,編譯器怎麼會預先知道 typename 實參是什麼呢?因此模板的例項化與定義體必須放到同一翻譯單元中。"[3]

[1] 任何時候都適用的20個c++技巧.  

[2] 為什麼不能將類模板的宣告與類模板函式實現分開寫.

[3]類模板和模板函式連線出錯處理.

c 模板的定義和實現

注意c c 模板的定義和實現 定義乙個類一般都是在標頭檔案中進行類宣告,在cpp檔案中實現,但使用模板時應注意目前的c 編譯器還無法分離編譯,最好將實現 和宣告 均放在標頭檔案中。如 test.h templateclass ctest test.cpp templatet ctest getval...

C 中的申明委託和事件

建立委託,對委託賦予事件,建立事件的執行介面,這樣一來,可以把事件真正的執行過程扔出到其他類中。委託可以執行不同的函式,委託的實質就是函式的呼叫 例如 在類cc中要執行事件a,申明委託d,可將d的執行過程扔出到類bb中。類cc public delegate void fileeventhandle...

c 中模板 類模板的宣告和定義

一 函式模板用法 1.1申明和定義 在函式申明和定義前面,加乙個模板template t,class c 就行,其餘正常定義和申明 呼叫時,跟正常函式一樣呼叫 注意 模板在呼叫時,才確定引數的具體型別!模板的宣告或定義只能在全域性,命名空間或類範圍內進行。即不能在區域性範圍,函式內進行,比如不能在m...