c++中的內部連線與外部連線
apr 22nd, 2007 by king
一.在學習內部連線與外部連線之前,必須先弄清楚幾個概念:
1.宣告
乙個宣告將乙個名稱引入乙個作用域。在c++中,在乙個作用域中重複乙個宣告是合法的。
以下都是宣告:
int foo(int,int); //函式前置宣告
typedef int int; //typedef 宣告
class bar; //類前置宣告
extern int g_var; //外部引用宣告
friend test; //友員宣告
using std::cout; //名字空間引用宣告
在同一作用域中可以多次重複以上宣告,但是有兩種宣告是不能重複的,那就是類成員函式及靜態資料成員的宣告:
class foo ;
2.定義
乙個定義提供乙個實體(型別、例項、函式)在乙個作用域的唯一描述。在同一作用域中不可重複定義乙個實體。
以下都是定義:
int y; //定義乙個整型變數
class foo ; //定義乙個類
struct bar ; //定義乙個結構體
foo* p; //定義乙個類指標
static int i; //定義乙個靜態整型變數
enum color; //定義乙個列舉
const double pi = 3.1415; //定義乙個double型常量
union rep; //定義乙個聯合
void test(int p) {}; //定義乙個函式
foo a; //定義乙個類例項
bar b; //定義乙個結構體例項
3.編譯單元
當乙個c或cpp檔案在編譯時,預處理器首先遞迴包含標頭檔案,形成乙個含有所有 必要資訊的單個原始檔,這個原始檔就是乙個編譯單元。這個編譯單元會被編譯成為乙個與cpp檔名同名的目標檔案(.o或是.obj)。連線程式把不同編譯單元中產生的符號聯絡起來,構成乙個可執行程式。
4.自由函式
如果乙個函式是自由函式,那麼這個函式不是類的成員函式,也不是友元函式。
二.內部連線和外部連線
1.內部連線:如果乙個名稱對於它的編譯單元來說是區域性的,並且在連線時不會與其它編譯單元中的同樣的名稱相衝突,那麼這個名稱有內部連線(注:有時也將宣告看作是無連線的,這裡我們統一看成是內部連線的)。
以下情況有內部連線:
a)所有的宣告
b)名字空間(包括全域性名字空間)中的靜態自由函式、靜態友元函式、靜態變數的定義
c)enum定義
d)inline函式定義(包括自由函式和非自由函式)
e)類的定義
在類中直接定義的函式相當於你寫inline,這個叫做隱式內聯,但是,不管是顯示內聯還是隱式內聯,都只是給編譯器乙個請求,最後是否被判斷成內聯,還得看你的功能模組的複雜度來決定的。
故不會發生類重複定義問題。
f)名字空間中const常量定義
g)union的定義
2.外部連線:在乙個多檔案程式中,如果乙個名稱在連線時可以和其它編譯單元互動,那麼這個名稱就有外部連線。
以下情況有外部連線:
a)類非inline函式總有外部連線,包括類成員函式和類靜態成員函式。
b)類靜態成員變數總有外部連線。
c)名字空間(包括全域性名字空間)中非靜態自由函式、非靜態友元函式及非靜態變數。
舉例說明:
a)宣告、enum定義、union定義有內部連線
所有的宣告、enum定義及union定義在編譯後不會產生連線符號,也就是在不同編譯單元中有相同名稱的宣告及enum、union定義並不會在連線時發生發現多個符號的錯誤。
// main.cpp
typedef int int; //typedef 宣告,內部連線
enum color; //enum定義,內部連線
union x //union定義,內部連線 ;
int main(void)
// a.cpp
typedef int int; //在a.cpp中重宣告乙個int型別別名,在連線時不會發生錯誤
enum color; //在a.cpp中重定義了乙個enum color,在連線時不會發生錯誤
const int i =blue; //const常量定義,內部連線
union x //union定義,內部連線 ;
b)名字空間中靜態自由函式、靜態友元函式、靜態變數、const常量定義有內部連線
// main.cpp
namespace test
//名字空間靜態函式定義,內部連線 }
static int i = 0; //全域性靜態變數定義,內部連線
static int foo() //全域性靜態函式定義,內部連線
const int k = 0; //全域性const常量定義,內部連線
int main(void)
namespace test
//名字空間函式定義,外部連線
}int i = 0;//全域性變數定義,外部連線
int k = 0;//全域性變數定義,外部連線
int foo() //全域性函式定義,外部連線
在全域性名字空間中,main.cpp中定義了靜態變數i,常量k,及靜態自由函式foo等,這些都有內部連線。如果你將這些變數或函式的static或是const修飾符去掉,在連線時就會現multiply defined symbols錯誤,它們與a.cpp中的全域性變數、全域性函式發生衝突。
c 內部鏈結 外部鏈結
c 內部鏈結與外部鏈結 2009年03月12日 星期四 11 07 在說內部連線與外部連線前,先說明一些概念。1.宣告 乙個宣告將乙個名稱引入乙個作用域 在c 中,在乙個作用域中重複乙個宣告是合法的 以下都是宣告 int foo int,int 函式前置宣告 typedef int int type...
C 的內部鏈結與外部鏈結問題
在說內部連線與外部連線前,先說明一些概念。1.宣告 乙個宣告將乙個名稱引入乙個作用域 在c 中,在乙個作用域中重複乙個宣告是合法的,以下都是宣告 class bar 類前置宣告 typedef int int typedef 宣告 extern int g var 外部引用宣告 friend tes...
C 中的內部鏈結屬性。。。
template class myclass char const s hello myclassx error s is pointer to object with internal linkage 這裡 hello 是個內部鏈結 internal linkage 物件 但是 template ...