extern可以實現多文件共享同一個變量、const常量、函數。
下面結合幾個例子來講一下extern的相關性質(下述皆為多文件編譯):
例1:
//file1.cpp
#include<iostream>
using namespace std;
extern int count;
int main(){
cout<<count<<endl;
return 0;
}
//file2.cpp
int count=3;
...
將兩個文件一起編譯,則輸出會是3,因為file1使用了在file2中定義的全局變量count,全局變量也叫外部變量,具有外部鏈接性,意思就是可以被外部文件引用。
注意,當使用extern聲明變量時,要求被聲明的變量只能在一個文件中被定義,比如再有個file3里面也定義了一個名為count的全局變量,然后跟file1、file2一起編譯,那編譯器就會報錯,因為不知道要引用哪個count,這也被稱為單獨定義規則。
總而言之,在多文件程序中,可以在一個文件(且只能在一個文件)中定義一個外部變量。使用該變量的其他文件必須使用extern來聲明他。(摘自C++ Primer Plus)
例2:
//file1.cpp
#include<iostream>
using namespace std;
void f(int x){
if(x>3) return;
extern int count;
count++;
cout<<count<<endl;
f(x+1);
}
int main(){
f(1);
return 0;
}
//file2.cpp
int count=1;
...
上述例子中,file1和file2一起編譯,運行后的輸出是:
2
3
4
因為file1使用extern聲明的count實際上就是file2中的count(同一個存儲地址),file1只是聲明要引用file2中的count,而不是重新定義一個count,所以即使遞歸調用函數也不會影響count保留上一次的值。這一點跟用static定義一個內部變量很像,不同的是static定義的內部變量只能初始化一次,而extern聲明的變量不能初始化。
例3:
//file1.cpp
#include<iostream>
using namespace std;
extern const int x;
int main(){
cout<<x<<endl;
return 0;
}
//file2.cpp
extern const int x=5;
...
上述例子中,file1和file2一起編譯,運行后的輸出是5。顯然file1通過extern聲明引用了在file2中的const常量x。
但是為什么file1和file2都要加extern? 要如何實現多個文件共享一個const常量呢?
因為const聲明的常量它的鏈接性是內部的,默認是不能被其他文件用extern引用的。也就是說例1中說的單定義規則對它並不適用,所以即使在多個文件中定義同名的const常量,也不會有問題。
可以使用extern來覆蓋其默認的內部鏈接性,就像file2中做得那樣,並且只能在一個文件中被初始化。
```c++ 例4:
include
using namespace std;
extern void f(int x);
int main(){
f(2);
return 0;
}
include
using namespace std;
void f(int x){
cout<<x<<endl;
}
...
上述例子的輸出為2,file1中利用extern引用了file2中的extern。函數的鏈接性和常規變量類似,故例1中講的性質對函數都適用,不再贅述。
若想函數只在文件內部可見,可使用static關鍵字將函數的鏈接性設置為內部的。