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

2021-07-30 21:35:04 字數 1517 閱讀 4506

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

test.h

template

class ctest

;test.cpp

template

t& ctest::getvalue()

template

void ctest::setvalue(const t& _value)

在這兒test.cpp中的內容應放在test.h中,否則在生成最終可執行程式時就會出現錯誤(在鏈結時會出錯)。因為在編譯時模板並不能生成真正的二進位制**,而是在編譯呼叫模板類或函式的cpp檔案時才會去找對應的模板宣告和實現,在這種情況下編譯器是不知道實現模板類或函式的cpp檔案的存在,所以它只能找到模板類或函式的宣告而找不到實現,而只好建立乙個符號寄希望於鏈結程式找位址。但模板類或函式的實現並不能被編譯成二進位制**,結果鏈結程式找不到位址只好報錯了:lnk  2019 無法解析的外部符號

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

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

附: c++中每乙個物件所占用的空間大小,是在編譯的時候就確定的,在模板類沒有真正的被使用之前,編譯器是無法知道,模板類中使用模板型別的物件的所占用的空間的大小的。只有模板被真正使用的時候,比如a, a,編譯器才知道,模板套用的是什麼型別,應該分配多少空間int 4位元組  double 8位元組。這也就是模板類為什麼只是稱之為模板,而不是泛型的緣故。

既然是在編譯的時候,根據套用的不同型別進行編譯,那麼,套用不同型別的模板類實際上就是兩個不同的型別,也就是說,stack和stack是兩個不同的資料型別,他們共同的成員函式也不是同乙個函式,只不過具有相似的功能罷了。

所以模板類的實現,脫離具體的使用,是無法單獨的編譯的;把宣告和實現分開的做法也是不可取的,必須把實現全部寫在標頭檔案裡面。為了清晰,實現可以不寫在class後面的花括號裡面,可以寫在class的外面。

模板類 宣告與定義

模板類的宣告與定義 最近在編寫模板類時發現乙個問題 當把模板類分開為 h宣告檔案 和 cpp實現檔案時,在模板類的main檔案使用模板功能時,編譯結果完全正確,卻無法鏈結成功。但是,如果把main放到.cpp檔案中就沒有任何問題,或者把 cpp 和 h 檔案放在一起也沒有問題。於是摸索著學習,解決問...

模板類的宣告與定義

newhandlersupport.h 檔案 template class newhandlersupport template new handler newhandlersupport currenthandler template newhandlersupport newhandlersup...

類模板不能讓宣告和實現分離

寫模板類的時候出的問題,調了一晚上,就是鏈結出錯,於是搜尋引擎開始工作,搜到篇簡單的博文解釋,暫時做個標記吧 我們習慣是.h中放類的函式宣告,在.cpp中放類的函式定義,但在類模板中不能這樣做,如隨手寫了個demo測試了下 h中 cpp view plain copy pragma once tem...