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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++模板声明与实现分开--由此想到的编译,链接原理

發布時間:2025/3/18 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++模板声明与实现分开--由此想到的编译,链接原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題來源:當模板文件的實現與聲明分開在不同文件中時,鏈接時會提示找不到相應模板函數,如下

一,編譯和鏈接的大概原理:

1,編譯,遍歷工程的所有代碼文件,進行文件分析,這里的分析與文件后綴無關,并不是說以CPP文件為依據,源文件后綴名可以改為任何名字。

編譯以文件為單位,將此文件#include的所有文件拿進來,寫進此文件中,包含進來的東西可能是函數聲明,也可能是函數的實現體。

如果#include "test.h",則包含進來的是一些函數和變量的聲明,如果 #include "test.cpp",則其中的函數實現代碼也被包含進來了。

編譯的結果是一個obj文件,如test.cpp編譯后是一個test.obj文件,里面是匯編指令。

同時,編譯器有了該文件的一個清單,里面保存了 【函數簽名(聲明)】到【函數體實現】的映射

2,鏈接,對所有的obj文件進行拼接。

為什么要拼接?對于每個obj文件,其中若調用了其它文件的函數(外部調用),就需要知道此外部函數的具體實現,這在編譯時是不關心的。

這時候去所有obj文件中查找此外部函數的實現體,若有兩個以上的obj都有此實現,則鏈接出錯,因為函數實現不唯一了,這不允許。此錯誤就是常見的

XXX?已經在 xxx.obj中定義了,如下:

若查找結果唯一,則將此外部函數的實現插入到調用處。

?二,實例分析

1,一個頭文件被多個CPP包含時編譯鏈接正確,一個CPP文件被多個其它CPP文件包含時編譯正確,鏈接出錯,報錯為 XXX?已經在 xxx.obj中定義。

因為CPP中有函數的實現體,每被包含一次就多了一個實現,導致一個函數在不同CPP文件中被多次實現,重復了。

頭文件被多次包含為什么沒問題?關鍵是每個頭文件開頭都有宏 #pragma once,該宏確保了頭文件只會被包含一次

2,模板文件的特殊性。

模板文件只有在實例化時才能確定其具體的實現體,所以如果將模板文件的聲明和函數體分開在.h和.cpp中,當編譯cpp時,并不會產生函數的具體實現體。當在其它文件中#include "template.h"時,會提示找不到函數的定義。

解決方法:在需要使用模板函數的地方,#include "template.cpp",即包含它的CPP文件,而不是.h文件。

原因:使用模板函數的地方,比如 addobj<cube>(),傳了具體的模板類型給函數,這樣模板函數就能到CPP文件中找到對應的實現體將cube傳給模板參數而實例化了。

3,綜合的例子,若一個類中既有模板函數,又有非模板函數,那么只能將模板函數的聲明與定義寫在一個文件中,分開到兩個文件是不行的。

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的C++模板声明与实现分开--由此想到的编译,链接原理的全部內容,希望文章能夠幫你解決所遇到的問題。

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