C++內部鏈接和外部鏈接

  1. 當一個實現文件(.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 文件中.


特別說明:

  1. 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表示採用外部鏈接,因此其必須有某個地址保存其值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章