課程
/后端開發(fā)
/C++
/C++遠(yuǎn)征之封裝篇(上)
好像demo.cpp和Teacher.cpp沒有關(guān)系,為什么運(yùn)行demo.cpp可以用Teacher.cpp里的定義
2017-09-17
源自:C++遠(yuǎn)征之封裝篇(上) 6-2
正在回答
從語法上說:函數(shù)只要聲明了就可以使用(調(diào)用它),所以 cpp 文件只要 include 相應(yīng)的函數(shù)頭文件(頭文件中就是函數(shù)聲明)就可以使用這個(gè)函數(shù),并不需要知道函數(shù)的實(shí)現(xiàn)。
那么你是好奇“為什么代碼中沒有實(shí)現(xiàn)也可調(diào)用呢”? 這需要你明白什么是“編譯”和“鏈接”:
函數(shù)還是需要實(shí)現(xiàn)的,不過那是實(shí)現(xiàn)在其他 cpp 文件中的。
像這樣由多個(gè) cpp 構(gòu)成的程序,其中每個(gè) cpp 文件都是被編譯器單獨(dú)編譯的。每一個(gè) cpp 文件被稱為一個(gè)“編譯單元”。 注意編譯器無需得知函數(shù)實(shí)現(xiàn)即可編譯函數(shù)調(diào)用,它只要知道函數(shù)聲明(需要聲明只是為了進(jìn)行類型檢查)。
你可以想象的到,單個(gè) cpp 文件并不能單獨(dú)編譯成可執(zhí)行程序。這些 cpp 源碼文件的編譯結(jié)果需要“整合”起來,這就是鏈接。
進(jìn)行鏈接是鏈接器的工作,它會(huì)找到不同編譯單元間引用的變量和函數(shù),處理好它們之間的訪問和調(diào)用(這些具體是如何處理的你現(xiàn)在不用知道),然后綜合這些結(jié)果生成最終的可執(zhí)行程序。
所以就每個(gè) cpp 來說,它確實(shí)不用管它用的函數(shù)是在哪里實(shí)現(xiàn)的,因?yàn)楹罄m(xù)鏈接器會(huì)處理好這一切的。
假如某個(gè)使用的函數(shù)真的沒有被任何一個(gè) cpp 代碼實(shí)現(xiàn),那么最后鏈接器會(huì)發(fā)現(xiàn)它找不到這一函數(shù)的實(shí)現(xiàn),就會(huì)報(bào)“未定義引用”這樣的鏈接錯(cuò)誤。
其實(shí)在一開始學(xué)習(xí)時(shí)寫的那種很小的單文件程序中,你也使用了實(shí)現(xiàn)在其他地方的函數(shù)??! 那些 printf 之類的庫(kù)函數(shù)就是! ? 現(xiàn)在你回過頭想一下:你只是 include 了相應(yīng)的庫(kù)頭文件,就調(diào)用了 printf,你也沒有實(shí)現(xiàn) printf,但你同樣成功調(diào)用了它! ?實(shí)際上是你的編譯環(huán)境提供了庫(kù)函數(shù)的實(shí)現(xiàn)代碼,最后鏈接器會(huì)負(fù)責(zé)找到標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)并整合進(jìn)你的程序中。
瀟瀟_暮雨 提問者
onemoo 回復(fù) 瀟瀟_暮雨 提問者
源文件之間調(diào)用 ?extern 調(diào)用函數(shù) ?,如果調(diào)用的是自己編寫的頭文件就用 ?include "調(diào)用文件";
那是因?yàn)槟阍赿emo.cpp中加入了Teacher.cpp的頭文件(Teacher.h)
舉報(bào)
封裝--面向?qū)ο蟮幕?,本教程力求幫助小伙伴們即學(xué)即會(huì)
Copyright ? 2025 imooc.com All Rights Reserved | 京ICP備12003892號(hào)-11 京公網(wǎng)安備11010802030151號(hào)
購(gòu)課補(bǔ)貼聯(lián)系客服咨詢優(yōu)惠詳情
慕課網(wǎng)APP您的移動(dòng)學(xué)習(xí)伙伴
掃描二維碼關(guān)注慕課網(wǎng)微信公眾號(hào)
2017-09-21
從語法上說:函數(shù)只要聲明了就可以使用(調(diào)用它),所以 cpp 文件只要 include 相應(yīng)的函數(shù)頭文件(頭文件中就是函數(shù)聲明)就可以使用這個(gè)函數(shù),并不需要知道函數(shù)的實(shí)現(xiàn)。
那么你是好奇“為什么代碼中沒有實(shí)現(xiàn)也可調(diào)用呢”? 這需要你明白什么是“編譯”和“鏈接”:
函數(shù)還是需要實(shí)現(xiàn)的,不過那是實(shí)現(xiàn)在其他 cpp 文件中的。
像這樣由多個(gè) cpp 構(gòu)成的程序,其中每個(gè) cpp 文件都是被編譯器單獨(dú)編譯的。每一個(gè) cpp 文件被稱為一個(gè)“編譯單元”。 注意編譯器無需得知函數(shù)實(shí)現(xiàn)即可編譯函數(shù)調(diào)用,它只要知道函數(shù)聲明(需要聲明只是為了進(jìn)行類型檢查)。
你可以想象的到,單個(gè) cpp 文件并不能單獨(dú)編譯成可執(zhí)行程序。這些 cpp 源碼文件的編譯結(jié)果需要“整合”起來,這就是鏈接。
進(jìn)行鏈接是鏈接器的工作,它會(huì)找到不同編譯單元間引用的變量和函數(shù),處理好它們之間的訪問和調(diào)用(這些具體是如何處理的你現(xiàn)在不用知道),然后綜合這些結(jié)果生成最終的可執(zhí)行程序。
所以就每個(gè) cpp 來說,它確實(shí)不用管它用的函數(shù)是在哪里實(shí)現(xiàn)的,因?yàn)楹罄m(xù)鏈接器會(huì)處理好這一切的。
假如某個(gè)使用的函數(shù)真的沒有被任何一個(gè) cpp 代碼實(shí)現(xiàn),那么最后鏈接器會(huì)發(fā)現(xiàn)它找不到這一函數(shù)的實(shí)現(xiàn),就會(huì)報(bào)“未定義引用”這樣的鏈接錯(cuò)誤。
其實(shí)在一開始學(xué)習(xí)時(shí)寫的那種很小的單文件程序中,你也使用了實(shí)現(xiàn)在其他地方的函數(shù)??! 那些 printf 之類的庫(kù)函數(shù)就是! ? 現(xiàn)在你回過頭想一下:你只是 include 了相應(yīng)的庫(kù)頭文件,就調(diào)用了 printf,你也沒有實(shí)現(xiàn) printf,但你同樣成功調(diào)用了它! ?實(shí)際上是你的編譯環(huán)境提供了庫(kù)函數(shù)的實(shí)現(xiàn)代碼,最后鏈接器會(huì)負(fù)責(zé)找到標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)并整合進(jìn)你的程序中。
2017-09-17
源文件之間調(diào)用 ?extern 調(diào)用函數(shù) ?,如果調(diào)用的是自己編寫的頭文件就用 ?include "調(diào)用文件";
2017-09-17
那是因?yàn)槟阍赿emo.cpp中加入了Teacher.cpp的頭文件(Teacher.h)