extern關鍵字會提升變量或者函數的逼格,使得它們可以跨文件被訪問。話雖然是這麼說,使用這個關鍵字必須要注意一些東西。
首先,你得在cpp文件裏面實現這些全局變量和全局函數,這是最基本的,然後只需要在需要用到這些變量和函數的文件裏聲明一下,用extern修飾聲明,這樣弄完之後就可以隨意使用這些全局變量和全局函數了。請不要爲編譯器擔心,擔心它們找不到這些東西,只要你實現了,不怕編譯器找不到。
在別的文件裏寫一堆的extern聲明顯得特別不專業,也顯得代碼十分臃腫,有沒有好的做法呢?有的。
我們一般把所有的全局變量和全局函數都放在一個*.cpp文件裏面,然後用一個同名的*.h文件包含所有的函數和變量的聲明。用法的示例如下:
運行結果如下:
這樣處理之後只需要到用到的地方加入#include"Demo.h"一句即可,很方便吧!這麼幹方便了這些變量和全局函數的管理。
下面是關於extern關鍵字的一些說明:
(1)extern聲明外部函數
在A.cpp中使用B.cpp中的函數,需要extern聲明。定義的形式類似於:
extern int a;
這裏需要注意定義和聲明的區別,extern int a = 10;屬於定義了。
這麼幹肯定是編譯不通過的,因爲存在重定義,#include"Demo.h"這一句是單純的代碼替換,在Demo.cpp和main.cpp裏替換之後你自然發現全局變量被定義了兩次,肯定會報錯。一句話,聲明可以拷貝n次,但是定義只能定義一次。
(2)extern聲明全局變量
在A.cpp中使用B.cpp中的全局變量,需要extern聲明。
extern關鍵字的作用是告訴編譯器,在某個cpp文件中,存在這麼一個函數/全局變量。
函數的聲明類似於:
extern int sum(int, int);
函數的聲明語句中,關鍵字extern可以省略,因爲全局函數默認是extern類型的,因此也就出現了Demo.h中的狀況。
雖然用extern聲明瞭變量和函數之後,在別的文件裏就隨意使用了,但是你也千萬別忘了書寫變量和函數的實現,否則就會出現無法解析的外部符號,編譯無法通過。
還有一件很有趣的事情,如果你將前面的Demo.cpp改爲Demo.c的話,編譯器會告訴你說找不到變量和函數是無法解析的外部符號,怎麼辦呢?
之所以會出現這樣的原因,是因爲c++編譯器和c編譯器差異性的問題,C++語言在編譯的時候爲了解決函數的多態問題,會將函數名和參數聯合起來生成一箇中間的函數名稱,而C語言則不會,因此會造成鏈接時找不到對應函數的情況,我們是在main.cpp文件裏包含了Demo.h也就是在main.cpp裏面聲明瞭這麼一些變量和函數(代入即可),main.cpp裏面的聲明會被c++編譯器成處理中間的名稱,而Demo.c裏面的實現會被c編譯器處理,兩者處理的差異性(詳情可以看我後面提供的鏈接),導致問題多多。總之處理之後.c文件的實現和.cpp裏面的聲明不一致了,這也是導致找不到的原因,這個時候就必須用extren "C"了,告訴c++編譯器,請保持我的名稱,不要給我生成用於鏈接的中間函數名。
我們將Demo.h裏面的東西改一下寫法即可:
運行結果如上圖,特別要聲明一下__cplusplus,前面是兩個_,在.c文件沒有定義__cplusplus而cpp文件定義了__cplusplus,一不小心將__cplusplus寫成了_cplusplus會出現什麼呢?就是我下面的情況了。
說實話,結果我挺震驚的,在Demo.c文件中定義的函數跑出一個“這是一個c程序”,也沒什麼,在一個cpp文件中的函數跑出一個“這是一個c程序”,我就很震驚了,原因我也不清楚,不過基本就是上面的解決方案了,最後說一下不在Demo.c包含#include"Demo.h"的原因,因爲在extern “C”並不是爲C所支持,其實也不算吧!
因爲網上說.c文件沒有定義_cplusplus而cpp文件定義了_cplusplus,如果真是這樣在Demo.c包含#include"Demo.h"也不會出現問題,可是不知道是我的編譯器原因還是什麼的,c文件和cpp文件都沒定義_cplusplus,因此有可能Demo.c包含#include"Demo.h"出現問題,因爲爲了能在cpp文件中使用,Demo.h文件裏我一般要寫成#ifndef_cplusplus,此時若Demo.c包含#include"Demo.h",恰好c文件中也沒有定義_cplusplus,那麼extern “C”就暴露出來了,自然會錯。
ps:關於extern和extern “C”,有更好的講解,我就不班門弄斧了。
鏈接:http://pan.baidu.com/s/1o6CACga 密碼:xefl
extern關鍵字
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.