-
當一個實現文件(.cpp ...)編譯時,預處理器(CPP)首先遞歸的包含頭文件,形成一個保含有所有必要信息的單個源文件. 這個源文件稱爲 編譯單元.
內部連接 如果一個名稱對於它的編譯單元來說是局部的, 並且在連接的時候不可能與其它編譯單元中的同樣的名稱相沖突,則這個名稱具有內部連接.即具有內部連接的名稱不會被帶到目標文件中.
外部連接 在一個多文件程序中,如果一個名稱在連接時可以和其他編譯單元交互,那麼這個名稱就具有外部連接. 即具有外部連接的名稱會引入到目標文件中,由連接程序進行處理.這種符號在整個程序中必須是惟一的.
具有內部連接的定義包括:
- 加 static 前綴的全局變量定義.如: static int x;
- 枚舉類型的定義.如: enum Boolean {NO,YES };
- 類的定義. 如: class Point { int d_x; int d_y; ... };
- 內聯函數的定義.如: inline int operator==(const Point& left,const Point&right) { ... }
- union的定義.
- 名字空間中const常量定義
具有外部連接的定義包括:
- 非內聯的類成員函數.如: Point& Point::operator+=(const Point& right) { ... }
- 非內聯,非靜態的自由函數. 如: Point operator+(const Point& left, const Point& right) { ... }
- 非靜態的全局定義.
聲明本身不會將任何符合引入目標文件,所以聲明都是內部連接的.
某些聲明可以激活對一個外部連接定義的訪問,也許我們會很隨便的說這些聲明具有外部連接,如:
int f();
extern int i;
class Point { static int s_numPoints; ... }; /* 類靜態數據成員聲明具有外部連接, 該數據必須在另一個地方被定義,如: point.c int Point::s_numPoints; */還有一些聲明即不把什麼符號引入目標文件,也不能用來激活對外部連接定義的訪問,我們常常稱這類聲明具有內部連接,
typedef int INT;
class Point;
struct Point;把一個帶有外部連接的定義放在 .h 文件中都會引起錯誤.由於類的聲明和定義都是內部連接的,一般都放在 .h 文件中.
特別說明:
-
C++規定,有const修飾的變量,不但不可修改,還都將具有內部鏈接屬性,也就是隻在本文件可見。(這是原來C語言的static修飾字的功能,現在const也有這個功能了。)又補充規定,extern const聯合修飾時,extern將壓制const這個內部鏈接屬性。於是,extern char const s[]將仍然有外部鏈接屬性,但是還是不可修改的。 具體使用方法如下:
在cpp文件中:extern const int a=1;
在要使用該常量的cpp文件中:extern const int a;//也可以將其放到頭文件中
cout<<a<<endl;
當用extern修飾const變量將強制爲其分配內存,因爲extern表示採用外部鏈接,因此其必須有某個地址保存其值。