日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

分享 C++命名空间的解释

發布時間:2025/3/15 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分享 C++命名空间的解释 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分享 C++命名空間的解釋 2012-05-20 15:10:09

分類: C/C++

使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突。在C++中,變量、函數和類都是大量存在的。如果沒有命名空間,這些變量、函數、類的名稱將都存在于全局命名空間中,會導致很多沖突。比如,如果我們在自己的程序中定義了一個函數toupper(),這將重寫標準庫中的toupper()函數,這是因為這兩個函數都是位于全局命名空間中的。命名沖突還會發生在一個程序中使用兩個或者更多的第三方庫的情況中。此時,很有可能,其中一個庫中的名稱和另外一個庫中的名稱是相同的,這樣就沖突了。這種情況會經常發生在類的名稱上。比如,我們在自己的程序中定義了一個Stack類,而我們程序中使用的某個庫中也可能定義了一個同名的類,此時名稱就沖突了。

Namespace 關鍵字的出現就是針對這種問題的。由于這種機制對于聲明于其中的名稱都進行了本地化,就使得相同的名稱可以在不同的上下文中使用,而不會引起名稱的沖突。或許命名空間最大的受益者就是C++中的標準庫了。在命名空間出現之前,整個C++庫都是定義在全局命名空間中的(這當然也是唯一的命名空間)。引入命名空間后,C++庫就被定義到自己的名稱空間中了,稱之為std。這樣就減少了名稱沖突的可能性。我們也可以在自己的程序中創建自己的命名空間,這樣可以對我們認為可能導致沖突的名稱進行本地化。這點在我們創建類或者是函數庫的時候是特別重要的。

命名空間基礎

namespace 關鍵字使得我們可以通過創建作用范圍來對全局命名空間進行分隔。本質上來講,一個命名空間就定義了一個范圍。定義命名空間的基本形式如下:

namespace?名稱{//聲明}

在命名空間中定義的任何東西都局限于該命名空間內。

下面就是一個命名空間的例子,其中對一個實現簡單遞減計數器的類進行了本地化。在該命名空間中定義了計數器類用來實現計數;其中的upperboundlowerbound用來表示計數器的上界和下界。

演示命名空間

  • namespace CounterNameSpace
  • {

  • ????int upperbound;
  • ????int lowerbound;

  • ????class counter
  • ????{

  • ????????int count;
  • ?? public:
  • ???? counter(int n)
  • ???? {

  • ????????????if ( n <= upperbound ){
  • ????????????????count = n;
  • ????????????} else? {
  • ????????????????count = upperbound;
  • ????????????}
  • ????? }
  • ??? void reset(int n)
  • ???? {
  • ?????? if ( n < upperbound )
  • ????????????{
  • ????????????????count = n;
  • ????????????}
  • ????????}
  • ???? int run() {
  • ????? if ( count > lowerbound)
  • ?????? {
  • ????????????????return count--;
  • ?????? } else {
  • ????????????????return lowerbound;
  • ?????? }
  • ????? }
  • ????};
  • }
  • 其中的upperboundlowerbound和類counter都是有命名空間CounterNameSpace定義范圍的組成部分。

    在命名空間中聲明的標識符是可以被直接引用的,不需要任何的命名空間的修飾符。例如,在CounterNameSapce命名空間中,run()函數中就可以直接在語句中引用lowerbound

    點擊(此處)折疊或打開

  • if ( count > lowerbound)

  • {

  • return count--;

  • }
  • 然而,既然命名空間定義了一個范圍,那么我們在命名空間之外就需要使用范圍解析運算符來引用命名空間中的對象。例如,在命名空間CounterNameSpace定義的范圍之外給upperbound賦值為10,就必須這樣寫:

    CounterNameSpace::upperbound = 10;

    或者在CounterNameSpace定義的范圍之外想要聲明一個counter類的對象就必須這樣寫:

    CounterNameSpace::counter obj;

    一般來講,在命名空間之外想要訪問命名空間內部的成員需要在成員前面加上命名空間和范圍解析運算符。

    下面的程序演示了如何使用CounterNameSpace這個命名空間:

    演示命名空間

  • #include <iostream>
  • using namespace std;
  • namespace CounterNameSpace
  • {
  • ????int upperbound;
  • ????int lowerbound;

  • ??? class counter
  • ????{
  • ????????int count;
  • ? ? public:
  • ????????counter(int n)
  • ????????{
  • ????????????if ( n <= upperbound )
  • ????????????{
  • ????????????????count = n;
  • ????????????} else
  • ????????????{
  • ????????????????count = upperbound;
  • ????????????}
  • ????????}
  • ????????void reset(int n)
  • ????????{
  • ????????????if ( n < upperbound )
  • ??????????? {
  • ????????????????count = n;
  • ????????????}
  • ????????}
  • ????????int run()
  • ????????{
  • ????????? if ( count > lowerbound)
  • ????????????{
  • ????????????????return count--;
  • ????????????}
  • ????????????else
  • ????????????????return lowerbound;
  • ????????}
  • ????};
  • }

  • int main()
  • {
  • ?CounterNameSpace::upperbound = 100;
  • ?CounterNameSpace::lowerbound = 0;
  • ?CounterNameSpace::counter ob1(10);
  • ? int i;
  • ? do {
  • ?? i = ob1.run();???????
  • ?? cout << i << " ";
  • ?} while (i > CounterNameSpace::lowerbound);
  • ?cout << endl;
  • ?CounterNameSpace::counter ob2(20);
  • do {
  • ? ? i = ob2.run();
  • ??? cout << i << " ";
  • ????} while (i > CounterNameSpace::lowerbound);

  • ????cout << endl;
  • ??? ob2.reset(100);
  • ????do
  • ??? {? i = ob2.run();
  • ????????cout << i << " ";

  • ????} while (i > CounterNameSpace::lowerbound);
  • ????cout << endl;
  • ????return 0;
  • }
  • 請注意:counter類以及upperboundlowerbound的引用都是在前面加上了CounterNameSpace修飾符。但是,一旦聲明了counter類型的對象,就沒有必須在對該對象的任何成員使用這種修飾符了。因此ob1.run()是可以被直接調用的。其中的命名空間是可以被解析的。

    相同的空間名稱是可以被多次聲明的,這種聲明向相互補充的。這就使得命名空間可以被分割到幾個文件中甚至是同一個文件的不同地方中。例如:

    ?????

    點擊(此處)折疊或打開

  • namespace NS

  • {

  • int i;

  • }

  • ?

  • //...


  • namespace NS

  • {

  • ????int j;

  • }

  • 其中命名空間NS被分割成兩部分,但是兩部分的內容卻是位于同一命名空間中的。也就是NS。最后一點:命名空間是可以嵌套的。也就是說可以在一個命名空間內部聲明另外的命名空間。

    using關鍵字

    如果在程序中需要多次引用某個命名空間的成員,那么按照之前的說法,我們每次都要使用范圍解析符來指定該命名空間,這是一件很麻煩的事情。為了解決這個問題,人們引入了using關鍵字。using語句通常有兩種使用方式:

    using namespace?命名空間名稱;

    using?命名空間名稱::成員;

    第一種形式中的命名空間名稱就是我們要訪問的命名空間。該命名空間中的所有成員都會被引入到當前范圍中。也就是說,他們都變成當前命名空間的一部分了,使用的時候不再需要使用范圍限定符了。第二種形式只是讓指定的命名空間中的指定成員在當前范圍中變為可見。我們用前面的CounterNameSpace來舉例,下面的using語句和賦值語句都是有效的:

    using CounterNameSpace::lowerbound; //只有lowerbound當前是可見的

    lowerbound = 10; //這樣寫是合法的,因為lowerbound成員當前是可見的

    using CounterNameSpace; //所有CounterNameSpace空間的成員當前都是可見的

    upperbound = 100; //這樣寫是合法的,因為所有的CounterNameSpace成員目前都是可見的

    下面是我們對之前的程序進行修改的結果:

    使用using


  • #include <iostream>

  • ?

  • using namespace std;

  • ?

  • namespace CounterNameSpace

  • {

  • ????int upperbound;

  • ????int lowerbound;

  • ????class counter

  • ????{

  • ????????int count;

  • ????public:

  • ????????counter(int n)

  • ????????{

  • ????????????if ( n < upperbound)

  • ????????????{

  • ????????????????count = n;

  • ????????????}

  • ????????????else

  • ????????????{

  • ????????????????count = upperbound;

  • ????????????}

  • ????????}

  • ?

  • ????????void reset( int n )

  • ????????{

  • ????????????if ( n <= upperbound )

  • ????????????{

  • ????????????????count = n;

  • ????????????}

  • ????????}

  • ?

  • ????????int run()

  • ????????{

  • ????????????if ( count > lowerbound )

  • ????????????{

  • ????????????????return count--;

  • ????????????}
  • ????????????else
  • ????????????{
  • ????????????????return lowerbound;
  • ????????????}
  • ????????}
  • ????};
  • }
  • int main()

  • {

  • ????//這里只是用CounterNameSpace中的upperbound

  • ????using CounterNameSpace::upperbound;

  • ?

  • ????//此時對upperbound的訪問就不需要使用范圍限定符了

  • ????upperbound = 100;

  • ????//但是使用lowerbound的時候,還是需要使用范圍限定符的

  • ????CounterNameSpace::lowerbound = 0;

  • ????CounterNameSpace::counter ob1(10);

  • ????int i;

  • ?

  • ????do

  • ????{

  • ????????i = ob1.run();

  • ????????cout << i << " ";

  • ????}while( i > CounterNameSpace::lowerbound);

  • ????cout << endl;

  • ?

  • ????//下面我們將使用整個CounterNameSpace的命名空間

  • ????using namespace CounterNameSpace;

  • ????counter ob2(20);

  • ????do

  • ????{

  • ????????i = ob2.run();

  • ????????cout << i << " ";

  • ????}while( i > CounterNameSpace::lowerbound);

  • ????cout << endl;

  • ?

  • ????ob2.reset(100);

  • ????lowerbound = 90;

  • ????do

  • ????{

  • ????????i = ob2.run();

  • ????????cout << i << " ";

  • ????}while( i > lowerbound);

  • ?

  • ????return 0;

  • }

  • 上面的程序還為我們演示了重要的一點:當我們用using引入一個命名空間的時候,如果之前有引用過別的命名空間(或者同一個命名空間),則不會覆蓋掉對之前的引入,而是對之前引入內容的補充。也就是說,到最后,上述程序中的std和CounterNameSpace這兩個命名空間都變成全局空間了。

  • 沒有名稱的命名空間

  • 有一種特殊的命名空間,叫做未命名的命名空間。這種沒有名稱的命名空間使得我們可以創建在一個文件范圍里可用的命名空間。其一般形式如下:

  • namespace

  • {

  • ????//聲明

  • }

  • 我們可以使用這種沒有名稱的命名空間創建只有在聲明他的文件中才可見的標識符。也即是說,只有在聲明這個命名空間的文件中,它的成員才是可見的,它的成員才是可以被直接使用的,不需要命名空間名稱來修飾。對于其他文件,該命名空間是不可見的。我們在前面曾經提到過,把全局名稱的作用域限制在聲明他的文件的一種方式就是把它聲明為靜態的。盡管C++是支持靜態全局聲明的,但是更好的方式就是使用這里的未命名的命名空間。

    std命名空間

    標準C++把自己的整個庫定義在std命名空間中。這就是本書的大部分程序都有下面代碼的原因:

    using namespace std;

    這樣寫是為了把std命名空間的成員都引入到當前的命名空間中,以便我們可以直接使用其中的函數和類,而不用每次都寫上std::

    當然,我們是可以顯示地在每次使用其中成員的時候都指定std::,只要我們喜歡。例如,我們可以顯示地采用如下語句指定cout

    std::cout << “顯示使用std::來指定cout”;

    如果我們的程序中只是少量地使用了 std 命名空間中的成員,或者是引入 std 命名空間可能導致命名空間的沖突的話,我們就沒有必要使用 using namespace std; 了。然而,如果在程序中我們要多次使用 std 命名空間的成員,則采用 using namespace std; 的方式把 std 命名空間的成員都引入到當前命名空間中會顯得方便很多,而不用每次都單獨在使用的時候顯示指定
    轉載地址:http://blog.renren.com/share/730973714/7874424429

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的分享 C++命名空间的解释的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。