1. 程式人生 > >C++命名空間

C++命名空間

串處理 建立 我們 管理 ctr 轉載 但是 字符 space

轉載:https://www.cnblogs.com/zhoug2020/p/5972439.html

一、 為什麽需要命名空間(問題提出)

命名空間是ANSIC++引入的可以由用戶命名的作用域,用來處理程序中 常見的同名沖突。

在 C語言中定義了3個層次的作用域,即文件(編譯單元)、函數和復合語句。C++又引入了類作用域,類是出現在文件內的。在不同的作用域中可以定義相同名字的變量,互不於擾,系統能夠區別它們。

1、全局變量的作用域是整個程序,在同一作用域中不應有兩個或多個同名的實體(enuty),包括變量、函數和類等。

例:如果在文件中定義了兩個類,在這兩個類中可以有同名的函數。在引用時,為了區別,應該加上類名作為限定:
class A //聲明A類
{ public:
void funl();//聲明A類中的funl函數
private:
int i; };
void A::funl() //定義A類中的funl函數
{…………}

class B //聲明B類
{ public:
    void funl(); //B類中也有funl函數
    void fun2(); };
void B::funl() //定義B類中的funl函數
{ …………}

這樣不會發生混淆。
在 文件中可以定義全局變量(global variable),它的作用域是整個程序。如果在文件A中定義了一個變量a int a=3;
在文件B中可以再定義一個變量a int a=5;
在分別對文件A和文件B進行編譯時不會有問題。但是,如果一個程序包括文件A和文件B,那麽在進行連接時,會報告出錯,因為在同一個程序中有兩個同名的變量,認為是對變量的重復定義。
可 以通過extern聲明同一程序中的兩個文件中的同名變量是同一個變量。如果在文件B中有以下聲明:
extem int a;
表示文件B中的變量a是在其他文件中已定義的變量。由於有此聲明,在程序編譯和連接後,文件A的變量a的作用域擴展到了文件B。如果在文件B中不再對a賦值,則在文件B中用以下語句輸出的是文件A中變量a的值: cout<

二、 什麽是命名空間(解 決方案)

命名空間:實際上就是一個由程序設計者命名的內存區域,程序設計者可以根據需要指定一些有名字的空間域,把一些全局實體分別放在各個命名空間中,從而與其他全局實體分隔開來。
如: namespace ns1 //指定命名中間nsl
{ int a;
double b; }
namespace 是定義命名空間所必須寫的關鍵字,nsl 是用戶自己指定的命名空間的名字(可 以用任意的合法標識符,這裏用ns1是因為ns是namespace的縮寫,含義請楚),在花括號內是聲明塊,在其中聲明的實體稱為命名空間成員(namespace member)。現在命名空間成員包括變量a和b,註意a和b仍然是全局變量,僅僅是把它們隱藏在指定的命名空間中而已。如果在程序中要使用變量a和b,必須加上命名空間名和作用域分辨符“::”,如nsl::a,nsl::b。這種用法稱為命名空間限定(qualified),這些名字(如nsl::a)稱為被限定名 (qualified name)。C++中命名空間的作用類似於操作系統中的目錄和文件的關系,由於文件很多,不便管理,而且容易重名,於是人們設立若幹子目錄,把文件分別放到不同的子目錄中,不同子目錄中的文件可以同名。調用文件時應指出文件路徑。
命名空間的作用:是建立一些互相分隔的作用域,把一些全局實體分隔開來。以免產生老點名叫李相國時,3個人都站起來應答,這就是名字沖突,因為他們無法辨別老師想叫的是哪一個李相國,同名者無法互相區分。為了避免同名混淆,學校把3個同名的學生分在3個班。這樣,在小班點名叫李相國時,只會有一個人應答。也就是說,在該班的範圍(即班作用域)內名字是惟一的。如果在全校集合時校長點名,需要在全校範圍內找這個學生,就需要考慮作用域問題。如果校長叫李相國,全校學生中又會有3人一齊喊“到”,因為在同一作用域中存在3個同名學生。為了在全校範圍內區分這3名學生,校長必須在名字前加上班號,如高三甲班的李相國,或高三乙班的李相國,即加上班名限定。這樣就不致產生混淆。
可以根據需要設置許多個命名空間,每個命名空間名代表一個不同的命名空間域,不同的命名空間不能同名。這樣,可以把不同的庫中的實體放到不同的命名空間中,或者說,用不同的命名空間把不同的實體隱蔽起來。過去我們用的全局變量可以理解為全局命名空間,獨立於所有有名的命名空間之外,它是不需要用 namespace聲明的,實際上是由系統隱式聲明的,存在於每個程序之中。
在聲明一個命名空間時,花括號內不僅可以包括變量,而且還可以包括以下類型:
·變量(可以帶有初始化);
·常量;
·數(可以是定義或聲明);
·結構體;
·類;
·模板;
·命名空間(在一個命名空間中又定義一個命名空間,即嵌套的命名空間)。
例如
namespace nsl
{ const int RATE=0.08; //常量
doublepay; //變量
doubletax() //函數
{return a*RATE;}
namespacens2 //嵌套的命名空間
{int age;}
}
如果想輸出命名空間nsl中成員的數據,可以采用下面的方法:
cout<

三、 使用命名空間解決名字沖突(使用指南)

有了以上的基礎後,就可以利用命名空間來解決名字沖突問題。現在,對例4程序進行修改,使之能正確運行。
例5 利用命名空間來解決例4程序名字沖突問題。
修改兩個頭文件,把在頭文件中聲明的類分別放在兩個不同的命名空間中。
//例8.5中的頭文件1,文件名為header1.h
using namespace std;
#include
#include
namespace ns1 //聲明命名空間ns1
{ class Student //在命名空間nsl內聲明Student類
{ public:
Student(int n,string nam,int a)
{ num=n;name=nam;age=a;}
void get_data();
private:
int num;
string name;
int age; };
void Student::get_data() //定義成員函數
{ cout<

四、 使用命名空間成員的方法

從上面的介紹可以知道,在引用命名空間成員時,要用命名空間名和作用域分辨符對命名空間成員進行限定,以區別不同的命名空間中的同名標識符。即:
命名空間名::命名空間成員名
這種方法是有效的,能保證所引用的實體有惟一的名字。但是如果命名空間名字比較長,尤其在有命名空間嵌套的情況下,為引用一個實體,需要寫很長的名字。在一個程序中可能要多次引用命名空間成員,就會感到很不方便。
1 、使用命名空間別名
可以為命名空間起一個別名(namespace alias),用來代替較長的命名空間名。如
namespace Television //聲明命名空間,名為Television
{ … }
可以用一個較短而易記的別名代替它。如:
namespace TV=Television; //別名TV與原名Television等價
也可以說,別名TV指向原名Television,在原來出現Television的位置都可以無條件地用TV來代替。
2、使用using命名空間成員名
using後面的命名空間成員名必須是由命名空間限定的名字。例如:
using nsl::Student;
以上語句聲明:在本作用域(using語句所在的作用域)中會用到命名空間ns1中的成員Student,在本作用域中如果使用該命名空間成員時,不必再用命名空間限定。例如在用上面的using聲明後,在其後程序中出現的Student就是隱含地指nsl::Student。
using聲明的有效範圍是從using語句開始到using所在的作用域結束。如果在以上的using語句之後有以下語句:
Student studl(101,”Wang”,18); //此處的Student相當於ns1::Student
上面的語句相當於
nsl::Student studl(101,”Wang”,18);
又如
using nsl::fun; //聲明其後出現的fun是屬於命名空間nsl中的fun
cout<

五、 無名的命名空間

以上介紹的是有名字的命名空間,C++還允許使用沒有名字的命名空間,如在文件A中聲明了以下的無名命名空間:
namespace //命名空間沒有名字
{ void fun( ) //定 義命名空間成員
{ cout<<”OK.”<

六、標準命名空間std

為了解決C++標準庫中的標識符與程序中的全局標識符之間以及不同庫中的標識符之間的同名沖突,應該將不同庫的標識符在不同的命名空間中定義(或聲明)。標準C++庫的所有的標識符都是在一個名為std的命名空間中定義的,或者說標準頭文件(如iostream)中函數、類、對象和類模板是在命名空間 std中定義的。std是standard(標準)的縮寫,表示這是存放標準庫的有關內容的命名空間,含義請楚,不必死記。
這樣,在程序中用到C++標準庫時,需要使用std作為限定。如
std::cout<<”OK.”<

七、 使用早期的函數庫

C語言程序中各種功能基本上都是由函數來實現的,在C語言的發展過程中建立了功能豐富的函數庫,C++從C語言繼承了這份寶貴的財富。在C++程序中可以使用C語言的函數庫。
如果要用函數庫中的函數,就必須在程序文件中包含有關的頭文件,在不同的頭文件中,包含了不同的函數的聲明。
在C++中使用這些 頭文件有兩種方法。
1、用C語言的傳統方法
頭文件名包括後綴.h,如stdio.h,math.h等。由於C語言沒有命名空間,頭文件並不存放在命名空間中,因此在C++程序文件中如果用到帶後綴.h的頭文件時,不必用命名空間。只需在文件中包含所用的頭文件即可。如
#include
2、用C++的新方法
C++標準要求系統提供的頭文件不包括後綴.h,例如iostream、string。為了表示與C 語言的頭文件有聯系又有區別,C++所用的頭文件名是在C語言的相應的頭文件名(但不包括後綴.h)之前加一字母c。例如,C語言中有關輸入與輸出的頭文件名為stdio.h在C++中相應的頭文件名為cstdio。C語言中的頭文件math.h,在C++中相應的頭文什名為cmath。C語言中的頭文件 string.h在C++中相應的頭文件名為cstring。註意在C++中,頭文件cstnng和頭文件strmg不是同一個文件。前者提供C語言中對字符串處理的有關函數(如strcmp,ctrcpy)的聲明,後者提供C++中對字符串處理的新功能。
此外,由於這些函數都是在命名空間std中聲明的,因此在程序中要對命名空間std作聲明。如:
#include
#include
using namespace std;
目前所用的大多數C++編譯系統既保留了c的用法,又提供丁C++的新方法。下面兩種用法等價,可以任選。
C傳 統方法 C++新方法
#include #include
#include #include
#include #include
using namespace std;
可以使用傳統的c方法,但應當提倡使用C++的新方法。

C++命名空間