1. 程式人生 > >C++中的名字空間

C++中的名字空間

C++中引入了名字空間(namespace)的概念。名字空間有兩方面的用途,一是將邏輯上相關的元素組織在一起,更重要的一點是解決函式和變數重名問題。

名稱空間的定義方式如下:

namespace 名字空間名稱
{
    //宣告和定義
}

當在一個名字空間內訪問另一個名字空間的函式、變數等時,需要額外新增限定詞形如“名字空間名稱::變數或函式名”。訪問同一個名字空間的函式不需要限定符。

/****************************************
 * using_namespace_1.cpp                *
 *                                      *
* C++名字空間的使用 * ****************************************/ #include <iostream> namespace namespace1 { int x = 5; } namespace namespace2 { int y = 10; void PrintY() { std::cout<<"y="<<y<<std::endl; } void PrintX() { std::cout<<"x="<<namespace1::x<<std::endl;
} } int main() { namespace2::PrintX(); namespace2::PrintY(); return 0; }

使用名稱空間
當在一個程式碼塊中需要多次使用同一個限定符或使用多個限定符時,可以在變數或函式等元素使用之前,使用名字空間宣告語句將名字空間中的所有元素或名字空間中特定的元素引入到本名稱空間。相應地,名字空間宣告語句包含兩類,一類是引入某個名稱空間中特定的元素,

using 名字空間名稱::特定元素名稱;

一類是引入某個名稱空間中所有的元素,

using namespace 名字空間名稱;
/****************************************
 * using_namespace_2.cpp                *
 *                                      *
 * C++名字空間的使用                    *
 ****************************************/
#include <iostream> namespace namespace1 { int x = 5; int y = 15; } namespace namespace2 { int z = 10; int m = 20; } namespace namespace3 { using namespace1::x; using namespace1::y; void PrintX() { std::cout<<"x="<<x<<std::endl; } void PrintY() { std::cout<<"y="<<y<<std::endl; } } namespace namespace4 { using namespace namespace2; void PrintZ() { std::cout<<"Z="<<z<<std::endl; } void PrintM() { std::cout<<"m="<<m<<std::endl; } } int main() { using namespace3::PrintX; PrintX(); using namespace namespace4; PrintZ(); PrintM(); return 0; }

使用名稱空間
可以定義沒有名稱的名字空間,稱為無名名字空間

namespace
{
  //宣告
}

無名名字空間中宣告的元素可以在本編譯單位(預處理後形成的定義檔案)中可用。不同編譯單位的名字空間互不相同。

/****************************************
 * using_namespace_3.cpp                *
 *                                      *
 * C++名字空間的使用                    *
 ****************************************/

#include <iostream>

namespace
{
  int x = 5;
}

namespace
{
  int y = 10;

  void PrintY()
  {
    std::cout<<"y="<<y<<std::endl;
  }

  void PrintX()
  {
    std::cout<<"x="<<x<<std::endl;
  }
}

int main()
{
  PrintX();
  PrintY();
  return 0;
}

無名名字空間
當使用某個名字空間中宣告的型別的元素作為函式的引數時,如果在該編譯單元中找不到該函式的定義,則自動去該型別宣告所在的名稱空間中去查詢相應函式。如果該函式是類的成
員函式,則優先從該類及其基類的成員函式中選擇。

/****************************************
 * using_namespace_4.cpp                *
 *                                      *
 * C++名字空間的使用                    *
 ****************************************/

#include <iostream>

namespace namespace1
{
  struct Test
  {
    int x;
    int y;
  };
  void Print(Test test)
  {
    std::cout<<"x = "<<test.x<<std::endl;
    std::cout<<"y = "<<test.y<<std::endl;
  }
}

namespace namespace2
{
  void PrintX(namespace1::Test test)
  {
    /*沒有顯式引入Print,但由於引數型別是*
     *namespace1的,所以可以查到該函式   */
    Print(test);
  }
}

int main()
{
  namespace1::Test a = {10,20};
  namespace2::PrintX(a);
  return 0;
}

名字空間查詢
可以為名字空間指定別名,使用以下命令:

namespace 新名字空間名稱 = 舊名字空間名稱;

名字空間別名可以用作原名字空間中的限定符,但不能通過該別名來副檔名字空間(新增新的宣告或定義等)。

/****************************************
 * using_namespace_5.cpp                *
 *                                      *
 * C++名字空間的使用                    *
 ****************************************/

#include <iostream>

namespace namespace1
{
  int x = 5;
}

namespace namespace2
{
  int y = 10;

  void PrintY()
  {
    std::cout<<"y="<<y<<std::endl;
  }

  void PrintX()
  {
    std::cout<<"x="<<namespace1::x<<std::endl;
  }
}

int main()
{
  namespace NNN = namespace2;
  NNN::PrintX();
  NNN::PrintY();
  return 0;
}

名字空間別名

參考文獻

1.Bjarne Stroustrup著,裘宗燕譯. C++程式設計語言(特別版).機械工業出版社 2009.