1. 程式人生 > 其它 >C++中模板類的編譯過程

C++中模板類的編譯過程

原文連結:https://blog.csdn.net/u011201045/article/details/38679417

首先要明白,C++中每一個物件所佔的空間大小,物件的記憶體分佈都是在編譯時期就確定下來的。而對於模板類來說,物件佔空間的大小和記憶體分佈是不知道的,依所套用的型別而定,比如A為模板類,則A<int>類物件所佔的空間大小和記憶體分佈顯然不同於A<double>。(這裡插一句,雖然模板類中有一個類字,但是對於例項化的模板類才算是真正的類,未例項化的模板類還不能算是類。)因此,對於未例項化的模板類,編譯器無法確定其大小,所以略過對模板類的編譯,在編譯時只檢查一些與模板無關的錯誤。而此時如果模板類的宣告和定義中有錯誤的話,編譯器就檢查不到。

對於模板類,同樣舉個例子說明

test.h檔案:
template<class T>
class A
{
public:
void f();
}
test.cpp檔案:
#include "test.h"
template<class T>
void A<T>::f()
{
......
}
main.cpp檔案:
#include "test.h"
int main()
{
A<int> a;
a.f();
return 0;
}
同樣的,在編譯時,會生成兩個obj檔案,在main.obj檔案中找不到A<int>::f的實現,將其看做外部連結型別,需要在連結的時候從其他obj檔案中找到A<int>::f的二進位制碼,將其所在的地址給main.obj檔案。這時問題就出現了,在連結的時候,聯結器在test.obj中找不到A<int>::f的實現(因為A沒有被例項化),連結失敗,發出了“無法解析的外部命令”錯誤。因此,模板類的宣告和實現都放在.h檔案中就能解決了。

其實模板類的宣告和實現時可以分離編譯的,在test.cpp中對模板類進行例項化,如下

test.cpp檔案:
#include "test.h"
template<class T>
void A<T>::f()
{
......
}
template class A<int>;
這時就不會出現連結錯誤的情況了,但是這個方法還是有缺陷的,因為你不知道類的使用方會套用什麼型別,你需要對每個型別在cpp檔案中挨個例項化一次,這就很麻煩,尤其是使用方套用的型別是自己定義了一個類的話,還是會出現連結錯誤。

原文連結:https://blog.csdn.net/u011201045/article/details/38679417