命名空間是ANSIC++引入的能夠由用戶命名的做用域,用來處理程序中 常見的同名衝突。
在 C語言中定義了3個層次的做用域,即文件(編譯單元)、函數和複合語句。C++又引入了類做用域,類是出如今文件內的。在不一樣的做用域中能夠定義相同名字的變量,互不於擾,系統可以區別它們。ios
一、全局變量的做用域是整個程序,在同一做用域中不該有兩個或多個同名的實體(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<spa
命名空間:實際上就是一個由程序設計者命名的內存區域,程序設計者能夠根據須要指定一些有名字的空間域,把一些全局實體分別放在各個命名空間中,從而與其餘全局實體分隔開來。
如: 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<.net
從上面的介紹能夠知道,在引用命名空間成員時,要用命名空間名和做用域分辨符對命名空間成員進行限定,以區別不一樣的命名空間中的同名標識符。即:
命名空間名::命名空間成員名
這種方法是有效的,能保證所引用的實體有唯一的名字。可是若是命名空間名字比較長,尤爲在有命名空間嵌套的狀況下,爲引用一個實體,須要寫很長的名字。在一個程序中可能要屢次引用命名空間成員,就會感到很不方便。
1 、使用命名空間別名
能夠爲命名空間起一個別名(namespace alias),用來代替較長的命名空間名。如
namespace Television //聲明命名空間,名爲Television
{ … }
能夠用一個較短而易記的別名代替它。如:
namespace TV=Television; //別名TV與原名Television等價
也能夠說,別名TV指向原名Television,在原來出現Television的位置均可以無條件地用TV來代替。
二、使用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.」<code
爲了解決C++標準庫中的標識符與程序中的全局標識符之間以及不一樣庫中的標識符之間的同名衝突,應該將不一樣庫的標識符在不一樣的命名空間中定義(或聲明)。標準C++庫的全部的標識符都是在一個名爲std的命名空間中定義的,或者說標準頭文件(如iostream)中函數、類、對象和類模板是在命名空間 std中定義的。std是standard(標準)的縮寫,表示這是存放標準庫的有關內容的命名空間,含義請楚,沒必要死記。
這樣,在程序中用到C++標準庫時,須要使用std做爲限定。如
std::cout<<」OK.」<對象
C語言程序中各類功能基本上都是由函數來實現的,在C語言的發展過程當中創建了功能豐富的函數庫,C++從C語言繼承了這份寶貴的財富。在C++程序中可使用C語言的函數庫。
若是要用函數庫中的函數,就必須在程序文件中包含有關的頭文件,在不一樣的頭文件中,包含了不一樣的函數的聲明。
在C++中使用這些 頭文件有兩種方法。
一、用C語言的傳統方法
頭文件名包括後綴.h,如stdio.h,math.h等。因爲C語言沒有命名空間,頭文件並不存放在命名空間中,所以在C++程序文件中若是用到帶後綴.h的頭文件時,沒必要用命名空間。只需在文件中包含所用的頭文件便可。如
#include
二、用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++的新方法。繼承