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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM