模板類成員函式的定義和宣告為什麼要放在一個檔案中
“通常情況下,你會在.h檔案中宣告函式和類,而將它們的定義放置在一個單獨的.cpp檔案中。但是在使用模板時,這種習慣性做法將變得不再有用,因為當例項化一個模板時,編譯器必須看到模板確切的定義,而不僅僅是它的宣告。因此,最好的辦法就是將模板的宣告和定義都放置在同一個.h檔案中。這就是為什麼所有的STL標頭檔案都包含模板定義的原因。”[1]
"標準要求編譯器在例項化模板時必須在上下文中可以檢視到其定義實體;而反過來,在看到例項化模板之前,編譯器對模板的定義體是不處理的——原因很簡單,編譯器怎麼會預先知道 typename 實參是什麼呢?因此模板的例項化與定義體必須放到同一翻譯單元中。"[1]
"《C++程式設計思想》第15章(第300頁)說明了原因:
模板定義很特殊。由template<…> 處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被一個模板例項告知。在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。"[2]
"對C++編譯器而言,當呼叫函式的時候,編譯器只需要看到函式的宣告。當定義類型別的物件時,編譯器只需要知道類的定義,而不需要知道類的實現程式碼。因此,因該將類的定義和函式宣告放在標頭檔案中,而普通函式和類成員函式的定義放在原始檔中。
但在處理模板函式和類别範本時,問題發生了變化。要進行例項化模板函式和類别範本,要求編譯器在例項化模板時必須在上下文中可以檢視到其定義實體;而反過來,在看到例項化模板之前,編譯器對模板的定義體是不處理的——原因很簡單,編譯器怎麼會預先知道 typename 實參是什麼呢?因此模板的例項化與定義體必須放到同一翻譯單元中。"[3]
[1] 任何時候都適用的20個C++技巧. http://www.uml.org.cn/c++/20112284.asp
[2] 為什麼不能將類别範本的宣告與類别範本函式實現分開寫. http://blog.sina.com.cn/s/blog_684355870100jmjr.html
[3]類别範本和模板函式連線出錯處理. http://www.cppblog.com/kenny/archive/2011/04/23/144841.html
[4]知乎上有一個能實現分開編譯的例子,但是很不人性化。。。http://www.zhihu.com/question/20630104
相關文章
- c++中模板類的成員函式的宣告與定義應該放在標頭檔案裡C++函式
- 類中成員函式宣告後面的const的含義!函式
- 一種將函式模板定義和宣告分開的方法函式
- 為什麼類中的執行緒函式必須要宣告靜態?執行緒函式
- 基類中定義的虛擬函式,子類中必須要覆蓋嗎?為什麼?函式
- c++中模板_類别範本的宣告和定義C++
- C++模板的定製四:定製成員函式和預設類參 (轉)C++函式
- 內部類中的成員的定義和使用
- C++ 的靜態成員變數為什麼一定要在類外定義C++變數
- 類别範本及其成員函式的定義及注意事項函式
- C++類將函式模板宣告為友元 例項C++函式
- 關於變數的宣告和定義、內部函式和外部函式變數函式
- 為什麼 C++ 中成員函式指標是 16 位元組?C++函式指標
- python函式的定義和呼叫是什麼?Python函式
- C++:類的成員函式C++函式
- 將framework檔案放在一個單獨的檔案中Framework
- 為什麼不在標頭檔案做定義
- TS定義陣列 ts宣告函式陣列函式
- C++ 類成員函式C++函式
- inittab檔案中的一個要設定的地方!
- C++模板的定製五:對定製成員函式的補充 (轉)C++函式
- 什麼是Python函式?如何定義函式?Python函式
- Shell中函式的定義和使用函式
- PHP獲取指定函式定義在哪個檔案中及行號PHP函式
- 想問一下你的那個模板檔案定義在根目錄下Template是通過什麼方式定義的?
- 類內的靜態成員函式函式
- 物件導向中類和物件的定義是什麼?物件
- const放在函式前和放在函式後函式
- c++中string類成員函式的總結C++函式
- 類成員函式作為map容器的value使用例項函式
- Java中可以宣告一個類為Static嗎?Java
- 函式指標使用c++類成員函式函式指標C++
- go中,iota要放在const的最前面來宣告Go
- C++模板的定製一:定製函式模板 (轉)C++函式
- Python如何定義一個函式Python函式
- C++ 函式過載,函式模板和函式模板過載,選擇哪一個?C++函式
- 一些常用的NLTK頻率分佈類中定義的函式函式
- OpenCV(cv::Mat 類的成員函式 ptr<T>())OpenCV函式