命名空間
在c++中,名稱(name)可以是符號常量、變數、巨集、函式、結構、列舉、類和物件等等。為了避免,在大規模程式的設計中,以及在程式設計師使用各種各樣的c++庫時,這些識別符號的命名發生衝突,標準c++引入了關鍵字namespace(命名空間/名字空間/命名空間/名域),可以更好地控制識別符號的作用域。
mfc中並沒有使用命名空間,但是在.net框架、mc++和c++/cli中,都大量使用了命名空間。
1)作用域與命名空間
l 相關概念
n 宣告域(declaration region)—— 宣告識別符號的區域。如在函式外面宣告的全域性變數,它的宣告域為宣告所在的檔案。在函式內宣告的區域性變數,它的宣告域為宣告所在的**塊(例如整個函式體或整個復合語句)。
n 潛在作用域(potential scope)—— 從宣告點開始,到宣告域的末尾的區域。因為c++採用的是先宣告後使用的原則,所以在宣告點之前的宣告域中,識別符號是不能用的。即,識別符號的潛在作用域,一般會小於其宣告域。
n 作用域(scope)—— 識別符號對程式可見的範圍。識別符號在其潛在作用域內,並非在任何地方都是可見的。例如,區域性變數可以遮蔽全域性變數、巢狀層次中的內層變數可以遮蔽外層變數,從而被遮蔽的全域性或外層變數在其倍遮蔽的區域內是不可見的。所以,乙個識別符號的作用域可能小於其潛在作用域。
l 命名空間
命名空間(namespace)是一種描述邏輯分組的機制,可以將按某些標準在邏輯上屬於同乙個集團的宣告放在同乙個命名空間中。
原來c++識別符號的作用域分成**:**塊(,如復合語句和函式體)、類和全域性。現在,在其中的類和全域性之間,標準c++又新增了命名空間這乙個作用域級別。
命名空間可以是全域性的,也可以位於另乙個命名空間之中,但是不能位於類和**塊中。所以,在命名空間中宣告的名稱(識別符號),預設具有外部鏈結特性(除非它引用了常量)。
在所有命名空間之外,還存在乙個全域性命名空間,它對應於檔案級的宣告域。因此,在命名空間機制中,原來的全域性變數,現在被認為位於全域性命名空間中。
標準c++庫(不包括標準c庫)中所包含的所有內容(包括常量、變數、結構、類和函式等)都被定義在命名空間std(standard標準)中了。
2)定義命名空間
有兩種形式的命名空間——有名的和無名的。
命名空間的定義格式為:(取自c++標準文件)
named-namespace-definition:
namespace identifier
unnamed-namespace-definition:
namespace
namespace-body:
declaration-seqopt
即:(自己翻譯並改寫的)
有名的命名空間:
namespace 命名空間名
無名的命名空間:
namespace
命名空間的成員,是在命名空間定義中的花括號內宣告了的名稱。可以在命名空間的定義內,定義命名空間的成員(內部定義)。也可以只在命名空間的定義內宣告成員,而在命名空間的定義之外,定義命名空間的成員(外部定義)。
命名空間成員的外部定義的格式為:
命名空間名::成員名 ……
例如:// out.h
namespace outer // 命名空間inner的成員f()的內部定義,其中的i為outer::i
int i;
void g() // 命名空間inner的成員g()的內部定義,其中的i為inner::i
void h(); // 命名空間inner的成員h()的宣告
}void f(); // 命名空間outer的成員f()的宣告
// namespace inner2; // 錯誤,不能宣告子命名空間void outer::f() // 命名空間outer的成員f()的外部定義
void outer::inner::h() // 命名空間inner的成員h()的外部定義
// namespace outer::inner2 // 錯誤,不能在外部定義子命名空間
注意:不能在命名空間的定義中宣告(另乙個巢狀的)子命名空間,只能在命名空間的定義中定義子命名空間。
也不能直接使用「命名空間名::成員名 ……」定義方式,為命名空間新增新成員,而必須先在命名空間的定義中新增新成員的宣告。
另外,命名空間是開放的,即可以隨時把新的成員名稱加入到已有的命名空間之中去。方法是,多次宣告和定義同一命名空間,每次新增自己的新成員和名稱。例如:
namespace a // 現在a有成員i和f()
namespace a // 現在a有成員i、f()、j和g()
還可以用多種方法,來組合現有的命名空間,讓它們為我所用。例如:
namespace my_lib american_telephone_and_telegraph::string s1 // 使用不方便
= new american_telephone_and_telegraph::string(「grieg」);
namespace att = american_telephone_and_telegraph; // 定義別名
att::string s2 = new att::string(「bush」); // 使用方便
att::string s3 = new att::string(「nielsen」);
l 無名命名空間
標準c++引入命名空間,除了可以避免成員的名稱發生衝突之外,還可以使**保持區域性性,從而保護**不被他人非法使用。如果你的目的主要是後者,而且又為替命名空間取乙個好聽、有意義、且與別人的命名空間不重名的名稱而煩惱的話,標準c++還允許你定義乙個無名命名空間。你可以在當前編譯單元中(無名命名空間之外),直接使用無名命名空間中的成員名稱,但是在當前編譯單元之外,它又是不可見的。
無名命名空間的定義格式為:
namespace int main() {
i = 0; // 可直接使用無名命名空間中的成員i
f(); // 可直接使用無名命名空間中的成員f()
C 命名空間namespace
在c 中,名稱 name 可以是符號常量 變數 巨集 函式 結構 列舉 類和物件等等。為了避免,在大規模程式的設計中,以及在程式設計師使用各種各樣的c 庫時,這些識別符號的命名發生衝突,標準c 引入了關鍵字namespace 命名空間 名字空間 命名空間 名域 可以更好地控制識別符號的作用域。mfc...
C 命名空間 (Namespace)
命名空間的設計目的是提供一種讓一組名稱與其他名稱分隔開的方式。在乙個命名空間中宣告的類的名稱與另乙個命名空間中宣告的相同的類的名稱不衝突。命名空間的定義是以關鍵字 namespace 開始,後跟命名空間的名稱,如下所示 csharp view plain copy namespace namespa...
C 命名空間(Namespace)
命名空間的設計目的是提供一種讓一組名稱與其他名稱分隔開的方式。在乙個命名空間中宣告的類的名稱與另乙個命名空間中宣告的相同的類的名稱不衝突。命名空間的定義是以關鍵字namespace開始,後跟命名空間的名稱,如下所示 namespace namespace name 為了呼叫支援命名空間版本的函式或變...