所謂的分離編譯是指將宣告和定義分開來寫,即將乙個函式的宣告和定義放在.h和.cpp檔案中。
寫過模板的人應該都會發現當我們用上面的方式寫乙個函式的時候,只要在.cpp中包.h的標頭檔案,就沒什麼問題,但是如果寫模板的時候,就編譯鏈結不過去,就如下面這個例子:
#include
template
void func(const t&);
#include
using
namespace
std;
#include"func.h"
template
void func(const t& t)
在分離編譯模式下,func.cpp會生成乙個目標檔案func.obj,由於在func.cpp檔案中,並中沒有發生函式模板呼叫,所以不會將template例項化為template,也就是說在func.obj中無法找到關於模板函式func的實現**,在原始檔main.cpp中,雖然函式模板被呼叫,但由於沒有模板**,也不能將其實例化.這樣,在鏈結的時候就會出現func沒有被定義的錯誤。
乙個簡單的解決辦法就是將函式模板func< t>的定義寫到頭檔案func.h中。這樣的話,只要包含了這個標頭檔案,就會把函式模板的**包含進來,一旦發生函式呼叫,就可以依據函式模板**將其實例化。
這個辦法雖然簡單可行,但是有如下不足。
(1)函式模板的定義寫進了標頭檔案,暴露了函式模板的實現細節。
(2)不符合分離編譯模式的規則,因為分離編譯模式要求函式原型申明放在標頭檔案,定義放在原始檔。
注意:這樣做,如果在多個目標檔案中存在相同的函式模板例項化後的模板函式實體,連線時並不會報函式重定義的錯誤,這與普通函式不同,是c++對模板函式的特殊規定。
使用關鍵字export,在func.cpp裡定義函式模板的時候,將函式模板頭改為:
export
template
void func(const t& t);
其實這樣做是為了告訴編譯器,這個函式模板可能在其他原始檔中被例項化。但是。目前幾乎所以的編譯器都不支援關鍵字export,所以這種方法不推薦使用。
顯示例項化也稱外部例項化。模板不支援分離編譯的原因在於模板沒有例項化,從而導致的一系列問題,因此,在不發生函式呼叫的時候將函式模板例項化,或者在不使用類模板的時候將類模板例項化能更好的解決問題。
在func.cpp中將函式模板func顯示例項化為模板函式func
template
void func(const
int &>;
這樣,就可以在func.cpp產生模板函式func< int>的例項化**,編譯之後就會產生函式的二進位制**,供其它原始檔連線,程式就可以正常執行。當類模板的成員函式的實現定義在原始檔中,通過模板類的物件呼叫成員函式時也會出現找不到函式定義的錯誤,可以使用同樣的方法解決,不再贅述。 模板的分離編譯問題
所謂的分離編譯是指將宣告和定義分開來寫,即將乙個函式的宣告和定義放在.h和.cpp檔案中。寫過模板的人應該都會發現當我們用上面的方式寫乙個函式的時候,只要在.cpp中包.h的標頭檔案,就沒什麼問題,但是如果寫模板的時候,就編譯鏈結不過去,就如下面這個例子 includetemplate void f...
類模板的分離編譯問題
類模板的分離編譯,即模板類的定義和其模板成員函式 介面 的定義不在同一檔案中。如模板類的定義在.h標頭檔案中,同時在.h標頭檔案中宣告介面,而在模板類之外的.cpp檔案中定義介面。此時在main函式中,如果只引用.h標頭檔案,編譯會報錯。原因 大多數編譯器,不支援類模板的分離編譯!1 實現分離編譯 ...
模板的分離編譯
模板為什麼不支援分離編譯 要了解這個問題,我們先來看一下程式在計算機中的執行過程,用一幅圖簡單說明。在乙個規範的c 檔案中,我們通常把乙個檔案分為 檔案宣告,檔案實現和檔案測試三個部分。在一般的編譯環境中,h檔案的 都會擴充套件到.cpp裡面,然後編譯器對.cpp檔案編譯形成.obj檔案,cpp以分...