模板為什麼不支援分離編譯
要了解這個問題,我們先來看一下程式在計算機中的執行過程,用一幅圖簡單說明。
在乙個規範的c++檔案中,我們通常把乙個檔案分為:檔案宣告,檔案實現和檔案測試三個部分。
在一般的編譯環境中,.h檔案的**都會擴充套件到.cpp裡面,然後編譯器對.cpp檔案編譯形成.obj檔案,.cpp以分離的方式編譯完成後,經過聯結器連線生成.exe檔案。
我們來看乙個例子:
test.h
#include
using
namespace
std;
void fun();
test.cpp
#include"test.h"
void fun()
{}main.cpp
#include"test.h"
int main()
在這個例子中,test.cpp和main.cpp分別被編譯成各自不同的.obj檔案,當編譯器編譯 main.cpp 時,它所僅僅知道的只是main.cpp中所包含的test.h檔案中的乙個關於void fun();的宣告,所以,編譯器將這裡的 fun() 看作外部連線型別,即認為它的函式實現**在另乙個.obj檔案中,本例也就是test.obj。因此 main.obj 中沒有任何關於 f() 的**。這些**實際存在於test.cpp所編譯成的test.obj中。main對fun()的呼叫只會生成一條call指令,因為main.obj中沒有f()的實現**。至於尋找 f() 的實現**,那就是聯結器的任務了。找到以後將call f這個指令的呼叫位址換成實際的f的函式進入點位址。需要注意的是:聯結器實際上將工程裡的.obj「連線」成了乙個.exe檔案。
再來看乙個模板的例子
test.h
#include
using
namespace
std;
template
class aa
;test.cpp
#include"test.h"
template
void aa::fun()
main.cpp
#include"test.h"
int main()
在這裡,編譯器會報錯
模板僅在需要的時候才會例項化出來,所以,當編譯器只看到模板的宣告時,它不能例項化該模板,只能建立乙個具有外部連線的符號並期待聯結器能夠將符號的位址決議出來。然而當實現該模板的.cpp檔案中沒有用到模板的例項時,編譯器並不會去例項化
模板的分離編譯
模板不支援分離編譯 我們來分析一下模板為什麼不支援分離編譯呢,所謂的分離編譯就是我們在編寫程式的時候可能會出現如下的一種情況就是,我下面就是舉具體的例子了 template.h includeusing namespace std templateclass a template.cpp inclu...
類模板的分離編譯
一直覺得模板類是特別神奇的東西,它可以構造出不同型別的物件,使 更加的靈活。這個過程就是類模板的例項化。我們使用類的模板寫乙個stack類 include include seqlist1.h using namespace std templateclass container seqlist c...
模板的分離編譯問題
所謂的分離編譯是指將宣告和定義分開來寫,即將乙個函式的宣告和定義放在.h和.cpp檔案中。寫過模板的人應該都會發現當我們用上面的方式寫乙個函式的時候,只要在.cpp中包.h的標頭檔案,就沒什麼問題,但是如果寫模板的時候,就編譯鏈結不過去,就如下面這個例子 include template void ...