日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

模板的分离编译

發布時間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模板的分离编译 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
模板不支持分離編譯 我們來分析一下模板為什么不支持分離編譯呢,所謂的分離編譯就是我們在編寫程序的時候可能會出現如下的一種情況就是,(我下面就是舉具體的例子了) 代碼
//*****************template.h***********//
#include<iostream>
using namespace std;template<class T>
class A
{
public:void Show();
private:T a;
};//*****************template.cpp***********//
#include"template.h"template<class T>
void A<T>::Show()
{T m;cout << "hello" << endl;
}//*****************test.cpp***********//
#define _CRT_SECURE_NO_WARNINGS 1
#include"template.h"int  main()
{A<int> a;a.Show();return 0;
}
現象一 上面的程序中,我們調用的時候會出現如下的報錯 1>test.obj : error LNK2019: 無法解析的外部符號 "public: void __thiscall A<int>::Show(void)" (?Show@?$A@H@@QAEXXZ),該符號在函數 _main 中被引用 1>W:\Code\C++\TemptlateSeparateCompilation\Debug\TemptlateSeparateCompilation.exe : fatal error LNK1120: 1 個無法解析的外部命令 現象二 我們改一下代碼再來看一個現象,如果我們在主函數中把a.Show給注釋掉,然后在template.cpp把cout<<"hello"<<endl;改寫成cout<<"hello" 在進行編譯的時候,發現竟然沒有報錯,這就奇怪了吧 從預處理,編譯,匯編,鏈接的角度來分析問題 我們知道模板的一個特性,只有當調用的時候才會實例化它,而我們的程序從一開始的文本到最后的可執行程序經歷了四個過程,分別是預處理,編譯,匯編,鏈接,最后是在鏈接的時候出現了錯誤 一.預處理 在預處理的時候,會進行頭文件展開,這個時候會把頭文件中的函數聲明展開到test.cpp和template.cpp中 二.編譯 在編譯test.cpp時由于只能看到模板聲明而看不到實現,因此不會實例化模板函數,但此時不會報錯,因為編譯器認為模板定義在其它文件中,就把問題留給鏈接程序處理。 在編譯template.cpp的時候,編譯的時候會進行一些檢查,比如一些語法的檢查,然后生成匯編代碼,因為我們的模板函數是在調用的時候才會進行實例化,即只有在調用模板函數的時候才會生成代碼,但是在我們的編譯的時候,在template.cpp這個文件中是沒有對函數進行實例化,所以并沒有生成匯編的代碼,這也是上面的第二種情況為什么我們的代碼錯誤從卻沒有被檢查出來的原因,因為我們的根本就沒有生成匯編代碼 三.匯編 再來接著分析,在匯編的時候就是生成二進制代碼,然后是一個.obj文件,在linux下面是.o文件,同時生成一個符號表,符號表中放置的就是我們所有函數的地址。 四.鏈接. 當我們進行最后一步鏈接的時候,執行到a.Show();會去.ob文件中查找我們的函數地址,這里有一個符號表,但是因為我們沒有生成一個函數代碼,所以這個函數表是查找不到的,所以這個時候就會報上面的錯誤。 還需要分析的一個問題就是,為什么我們把函數的聲明和定義放置在一個文件中的時候就可以呢,因為如果我們把函數聲明和定義放置在一個頭文件中的話,我們在編譯的時候,就會頭文件展開了,這個時候調用了我們的函數,然后又是在一個文件內如就會直接直接生成代碼,然后在查找的時候就會很容易的查找到這個內容。 解決辦法 方法一: 使用上面說的內容,放模板函數的聲明和定義放在一個頭文件下面 但是這樣會出現一些問題 (1)放置在頭文件中,暴露了模板函數的 內容 (2)不符合分離編譯的原則 方法二 我們可以在函數聲明的時候加上一個export,就是下面的這種形式 export void Show(); 但是很多的編譯器是不支持的 方法三 我們可以顯示的實例化,就是我們可以在頭文件中對我們需要的內容 進行一個顯式的實例化

總結

以上是生活随笔為你收集整理的模板的分离编译的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。