日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Include Cpp?還可以這樣?

本文轉(zhuǎn)載自微信公眾號「程序喵大人」,作者程序喵大人  。轉(zhuǎn)載本文請聯(lián)系程序喵大人公眾號。

莊浪ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

前兩天突然看見部門有個項(xiàng)目的代碼里通篇全是#include "xxx.cpp",我表示從來沒見過這種寫法,引發(fā)了我的一些思考:

問題一:這啥玩意?

C++是一門高深莫測的語言,什么寫法都有,而且#include本質(zhì)上就是復(fù)制粘貼代碼,我也不敢說別人寫的不對,可能開發(fā)者是C++大佬,寫了一些我們普通人無法理解的代碼也是正常的。

問題二:整個項(xiàng)目都是這種引用方式,不會導(dǎo)致某一函數(shù)重復(fù)定義嗎?

為此我查了一些資料,并做了一些測試:

代碼段1:

  
 
 
 
  1. // file1.cc 
  2. #include  
  3.  
  4. using std::cout; 
  5.  
  6.  void ddd() { cout << "ddd \n"; } 

代碼段2:

  
 
 
 
  1. // file2.cc 
  2. #include "file1.cc" 
  3.  
  4. int main() { 
  5.     ddd(); 
  6.     return 0; 

代碼段3:

  
 
 
 
  1. // filec.cc 
  2. #include "file1.cc" 
  3.  
  4. void f() { 
  5.     ddd(); 

然后三個源文件一起編譯鏈接:

發(fā)現(xiàn)報錯了,的確出現(xiàn)了multiple definition的錯誤,確實(shí)一個函數(shù)不能有多個定義。我又改了下代碼:

  
 
 
 
  1. // file1.cc 
  2. #include  
  3.  
  4. using std::cout; 
  5.  
  6. inline void ddd() { cout << "ddd \n"; } 

將ddd函數(shù)改成了內(nèi)聯(lián)函數(shù),然后三個源文件一起編譯鏈接:

編譯成功且正常輸出。

我將普通函數(shù)改成成員函數(shù)又測試了一次:

代碼段1:

  
 
 
 
  1. file1.cc 
  2. #include  
  3.  
  4. using std::cout; 
  5.  
  6. struct A { 
  7.     int a_; 
  8.     void func(); 
  9. }; 
  10.  
  11. void A::func() { cout << "file1.cc a " << a_ << "\n"; } 

代碼段2:

  
 
 
 
  1. // file2.cc 
  2. #include "file1.cc" 
  3.  
  4. int main() { 
  5.     A a; 
  6.     a.func(); 
  7.     return 0; 

代碼段3:

  
 
 
 
  1. // filec.cc 
  2. #include "file1.cc" 
  3.  
  4. void f() { 
  5.     A a; 
  6.     a.func(); 

然后一起編譯鏈接:

發(fā)現(xiàn)成員函數(shù)這樣定義也會報錯,也會有multiple definition的錯誤,我又改了一下代碼:

  
 
 
 
  1. // file1.cc 
  2. #include  
  3.  
  4. using std::cout; 
  5.  
  6. struct A { 
  7.     int a_; 
  8.     void func() { cout << "file1.cc a " << a_ << "\n"; } 
  9. }; 

將函數(shù)的定義搬運(yùn)到了類中,編譯鏈接:

程序正常運(yùn)行,熟悉C++的朋友可能都知道原因,類中定義的函數(shù)就相當(dāng)于是內(nèi)聯(lián)函數(shù),所以編譯鏈接不會有問題。

所以得出結(jié)論:

  • 內(nèi)聯(lián)函數(shù)的定義可以被多個源文件引入(內(nèi)聯(lián)函數(shù)到最后其實(shí)不是個函數(shù))
  • 類的定義可以被多個源文件引入(這是必須的,要不然編譯器怎么知道類的對象布局)

問題三:貌似平時使用的模板就多數(shù)都定義在頭文件中,這個不會導(dǎo)致某一函數(shù)重復(fù)定義嗎?

直接看三段代碼吧:

代碼段1:

  
 
 
 
  1. // temp.h 
  2. #include  
  3.  
  4. template  
  5. struct B { 
  6.     T a; 
  7.     void ff() { std::cout << "temph \n"; } 
  8. }; 

代碼段2:

  
 
 
 
  1. // filec.cc 
  2. #include "temp.h" 
  3.  
  4. void f() { 
  5.     B a; 
  6.     a.ff(); 

代碼段3:

  
 
 
 
  1. // file2.cc 
  2. #include "temp.h" 
  3.  
  4. int main() { 
  5.     B a; 
  6.     a.ff(); 
  7.     return 0; 

所有源文件編譯鏈接:

發(fā)現(xiàn)編譯成功且正常運(yùn)行,那如果函數(shù)的定義不在類內(nèi)會怎么樣呢?

  
 
 
 
  1. // temp.h 
  2. #include  
  3.  
  4. template  
  5. struct B { 
  6.     T a; 
  7.     void ff(); 
  8. }; 
  9.  
  10. template  
  11. void B::ff() { 
  12.     std::cout << "temph \n"; 

程序編譯鏈接后:

編譯鏈接成功且輸出正常結(jié)果。

所以得出結(jié)論:編譯器對模板做了特殊處理,不論模板類中函數(shù)是否內(nèi)聯(lián),都可以正常鏈接。

這個結(jié)論其實(shí)不是我得出的(所以可信),而是gnu文檔(參考資料的最后一個鏈接)寫的,上述代碼只是為了印證結(jié)論。

大體意思如下:編譯器對模板做了特殊處理,如果函數(shù)不是內(nèi)聯(lián)函數(shù),那可以有兩種處理方式:

  1. 鏈接時隨機(jī)選擇一個定義,其它的丟棄掉
  2. 編譯器會把函數(shù)的定義單獨(dú)提出來,提到單獨(dú)一個文件中,對此文件單獨(dú)編譯,就不會出現(xiàn)重復(fù)定義的問題。

搞定,大家對此還有什么問題,歡迎留言!

參考資料

https://zybuluo.com/uuprince/note/81709

https://stackoverflow.com/questions/15866258/template-class-multiple-definition

https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html


當(dāng)前標(biāo)題:Include Cpp?還可以這樣?
文章鏈接:http://www.dlmjj.cn/article/djpdses.html