官术网_书友最值得收藏!

2.10 命名空間

1.命名空間

在最初的C++標準中并沒有對命名空間的支持,要求程序在全局作用域中聲明的每個變量、函數、類型、模板等都必須具有唯一的名稱,如果在同一程序中有兩個名稱相同的全局變量,將產生命名沖突。

如果在程序中引入另一個系統或第三方軟件商提供的庫文件,就必須保證程序中定義的全局名(包括變量、函數、類型等的名稱)都不能與所用庫中的名稱相同;如果一個程序由許多程序員共同編寫,大家也不能命名相同的全量變量名和函數名,否則將產生名字沖突,這就是所謂的全局命名空間污染問題,處理起來并不容易,在大型程序中尤其困難。最新的C++標準為了解決這個問題,引入了命名空間。

在一個命名空間中,可以定義許多不同的對象(包括變量、函數、類型、類等),并將這些對象的有效范圍局限在命名空間內。但在不同的命名空間中,可以定義同名的對象,只要兩個同名對象不在同一命名空間中,就不會引起沖突。

2.命名空間的定義

定義命名空間的關鍵字是namespace,它的語法如下:

namespace namespace_name{
   members
}

namespace_name是命名空間的名字,只要是一個合法的C++標識符都可以;merbers是命名空間中包括的成員,可以是變量、函數聲明、函數定義、結構聲明,類的聲明等。例如:

namespace ABC{
   int count;
   typedef float house_price;
   struct student{
     char *name;
     int age;
   };
   double add(int a,int b) {
      return (double)a+b;
      inline int min(int a,int b);
   }
}
int ABC::min(int a,int b) {
   return a>b?a:b;
};

這里定義了一個命名空間ABC,它有5個成員:count、house_price、student、add( )和min( ),有變量、結構、類型以及函數的聲明或定義。函數的定義有兩種方式:在命名空間內定義,如函數add( );也可以在命名空間外定義,如min()。當在命名空間外定義時,要用“命名空間::”作為函數名的前綴,表示該函數是屬于某個命名空間的成員,它的有效范圍僅在此命名空間內。

3.名字空間的應用

命名空間的成員的作用域局限于命名空間內部,可以通過作用域限定符::訪問它,語法如下:

namespace_name::identifier

identifier就是命名空間的成員名。例如,訪問上面的ABC命名空間中的成員:

void main(){
   ABC::count=1;  //訪問ABC空間中的count
   int count=9;   //main()函數中的count,與ABC中的count無關
   ABC::student s;  //用ABC空間中的student結構定義s
   s.age=9;
   int x=ABC::min(4,5);  //調用ABC中的min函數計算兩數最小值
}

另外,標準C++提供了using命令,它可將命名空間中的成員引入當前程序中,簡化了命名空間的使用。using有如下兩種使用方式。

① 引用命名空間的單個成員。用法如下:

using namespace_name::identifier

例如,用using簡化ABC命名空間中count的使用:

void main(){
   using ABC::count;    //L1
   count =2;       //L2
   //int count=9;      //L3
   ……
   count=count+2;     //L4
}

語句L1表示本程序使用ABC命名空間中的count變量。語句L3是錯誤的,因為main()中已經有了count,它是using從ABC命名空間引入的。如果沒有語句L1,則語句L2和L4應該寫成:

ABC::count=2        //L2
ABC::count= ABC::count+2  //L4

這樣的書寫顯然要麻煩得多。

② 引入命名空間的全部成員。用法如下:

using namespace_name

例如,用using將ABC命名空間的全部成員引入程序中:

using namespace ABC;   //L1
void main(){
   int count=9;       //錯誤,已有來源于ABC中的count,成了重復定義
   student s;
   count=5;
   s.age=min(43,32);
}

語句L1用using語句將ABC命名空間中的全部成員引入程序中,所以在main()中就可以直接使用來源于ABC中的任何成員了。

命名空間為全局名稱的沖突問題提供了一種解決方案。如果一個系統由多個文件組成,而每個文件又由不同的開發商或程序員提供,則開發商和程序員可以將他們定義的名稱局限在自定義的命名空間中,即使大家都定義了相同的名稱,也不會產生沖突。

4.std命名空間

C++經歷了較長的發展和標準化過程,結果形成了兩個版本的C++:一個是以Bjarne Stroustrup最初設計的C++為基礎的版本,稱為傳統C++;另一個是以ANSI/ISO標準化委員會創建的C++,稱為標準C++。

標準C++增加了傳統C++中沒有的一些特征,是傳統C++的超集。兩種版本的C++有大量相同的庫和函數(標準C++更多),其區分方法是頭文件和命名空間。傳統C++采用與C語言同樣風格的頭文件;標準C++為了兼容傳統C++,也支持C語言風格的頭文件,但它創建了一種新式的頭文件,為標準C++庫所使用。標準C++的新式頭文件沒有擴展名,即不需要 .h之類的擴展名。例如,傳統C++的頭文件有iostream.h、fstream.h、string.h,標準C++對應的頭文件有iostream、fstream、string。

標準C++包含了整個C函數庫,支持在C++程序中引用C函數,允許用#include把包含C函數庫的頭文件包含到程序中。但標準C++也提供了與之對應的新式函數庫,其命名方法是在原C函數庫對應頭文件名的前面加上“c”前綴,并去掉“.h”。例如,C語言的頭文件有stdio.h、ctype.h、math.h,標準C++頭文件有cstdio、cctype、cmath。

標準C++將新格式頭文件中的內容全部放到了std命名空間中,非新格式頭文件中的內容則被直接放到了全局命名空間中。當前的許多C++編譯器都提供了對兩種版本C++的支持,如果程序要引用標準C++新格式頭文件中的函數,就需要在程序中使用下面的語句將std命名空間中的名稱引入到全局命名空間中:

using namespace std;

例2-18】 標準C++程序設計的簡單程序。

//Eg2-18.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
using namespace std;
void main(){
   string s1="ddd",s2;    //string是字符串,定義于<string>
   s2=s1;         //字符串賦值,不需要strcpy函數
   int i;
   int s=sin(30);      //調用cmath庫中的sin函數
   scanf("%d",&i);     //scanf、printf來源于cstdio
   printf("i=%d\n",i);
   cin>>i;         //cin、cout來源于iostream
   cout<<"i="<<i<<endl;
   cout<<s2<<endl;
}

本程序的函數調用及數據類型來源于標準C++提供的新式庫函數,這些函數及數據類型來源于std命名空間,若去掉using namespace std,程序就會產生編譯錯誤。

語句“using namespace std;”會將std命名空間中的標識符都引入到程序中,如果只需用到std命名空間中的個別標識符,可以在要使用的標識符前面加上前綴std::,不必用“using namespace std;”將std中的全部名稱引入到程序中來。例如:

std::cout<<"not use using……"<<std::endl;
std::cout<<"not use using……\n";
std::cin<<xx;

雖然C++編譯器同時支持新、老格式頭文件,但由于新格式與C++新標準相符合,新標準C++具有傳統標準C++所沒有的新特性,功能更強大,因此應該多用新標準中的庫函數進行程序設計,常稱為標準C++程序設計。

主站蜘蛛池模板: 淮南市| 岳池县| 黄浦区| 南丰县| 句容市| 搜索| 禹州市| 新平| 南安市| 驻马店市| 林州市| 中阳县| 佛坪县| 孝感市| 山阳县| 镇雄县| 丽水市| 海原县| 清河县| 昆山市| 天镇县| 营口市| 姜堰市| 阿克| 道孚县| 日照市| 隆尧县| 财经| 华阴市| 南雄市| 分宜县| 莆田市| 海盐县| 汤原县| 白河县| 应城市| 海兴县| 色达县| 灵台县| 卢氏县| 汉源县|