天天看點

C++:02---命名空間

一、概念:

  • ①類似于倉庫,空間記憶體儲代碼,需要用到時調用
  • ②也為防止名字沖突提供了更加可控的機制

二、命名空間的定義

  • 定義的基本格式如下:
namespace  命名空間名
 
{
 
//一系列聲明與定義
 
};      

三、命名空間的注意事項

  • 命名空間定義時最後的分号可有可無
  • 隻要出現在全局作用域中的聲明都可置于命名空間内:類、變量定義(及其初始化)、函數聲明(及其定義)、模闆、其它命名空間....等
  • 命名空間可以嵌套 

四、命名空間的使用

  • 方式:先using聲明命名空間,然後直接使用命名空間内代碼
//例
 
namespace mySpace
 
{
 
int a=1;
 
void fun();//聲明函數
 
namespace ns //命名空間的嵌套
 
{
 
};
 
};
 
void mySpace::fun() //定義函數要帶上命名空間作用域限定符
 
{
 
cout<<"mySpace";
 
}      

命名空間的聲明

//聲明mySpace命名空間,空間内所有代碼都可使用

using namespace mySpace;

//聲明mySpace命名空間内的fun函數,隻有fun函數可供外界使用

using namespace mySpace::fun;

//聲明mySpace命名空間内的ns命名空間,隻有ns命名空間可供外界使用

using namespace mySpace::ns;

命名空間的使用

  • 使用命名空間内代碼時可直接使用,也可以在前面加上命名空間名

using namespace mySpace;

int main()

{

cout<<a;

cout<<mySpace::a;

fun();

mySpace::fun();

return 0;

}

五、多個命名空間使用、以及作用域的關系

  • 1.多個命名空間使用時,如果變量、函數名等重名時,使用時需要加上作用域限定符
namespace ns1
 
{
 
int a=1;
 
}
 
namespace ns2
 
{
 
int a=2;
 
}
 
using namespace::ns1;
 
using namespace::ns2;
 


 
int main()
 
{
 
cout<<a;//錯誤,産生二義性
 


 
cout<<ns1::a;//1
 
cout<<ns2::a;//2
 
}      
  • 2. 命名空間變量、函數等與全局變量的重名時,使用時需要加上作用域限定符
  • 全局變量的在前面加上::,命名空間的在前面加上命名空間名
namespace ns1
 
{
 
int a=1;
 
}
 
using namespace::ns1;
 
int a=2;
 


 
int main()
 
{
 
cout<<a;//錯誤,産生二義性
 


 
cout<<::a; //列印全局變量
 
cout<<ns1::a;
 
}      
  • 3.命名空間變量、函數等與局部變量重名時。如果不加作用域限定符,局部變量會覆寫命名空間内成員
  • 此處的作用域限定符可以直接加::,或者加上命名空間名
namespace ns1
 
{
 
int a=1;
 
}
 
using namespace::ns1;
 
int main()
 
{
 
int a=2;
 
cout<<a; //2
 


 
cout<<::a;//1
 
cout<<ns1::a;//1
 
}      

六、未命名的命名空間

  • 1.在定義時省去命名空間名:
namespace
 
{
 
int a=1;
 
void fun();
 
}      
  • 2.特點:
  • 擁有靜态生命周期,取代了C語言中的static,使得其在整個檔案中有效,其他檔案無效
  • 還可嵌套其它命名空間
  • 命名空間内的名字要與其作用域的其它名字有所差別,否則産生二義性

七、命名空間取别名

  • 方法:直接用=号取别名
namespace ns1
 
{
 
int a=1;
 
};
 
namespace ns2=ns1;//取别名
 


 
using namespace ns2;//實質就是對ns1的聲明      

八、using聲明與using訓示的差別

  • using聲明:一條using聲明一次隻能引入命名空間内的一個成員,它使得程式知道我們所用的是哪個空間内的名字
  • using訓示:一條using訓示将命名空間内的所有成員都變的可見,聲明了所有成員
namespce A
 
{
 
int i,j;
 
}
 
using namespace A;//using訓示
 
using A::i;//using聲明
 
using A::j;//using聲明      
  • 注意:
  • 避免使用using訓示,原因:因為隻要一條using訓示,命名空間内的所有成員都變得可見,這會與其作用域的其它名稱産生沖突,造成很嚴重的污染問題。并且會産生很多的二義性
  • 是以,我們建議,盡量使用using聲明
//例如我們使用命名空間std的cout和cin。不要直接使用using namespace std;
 
#include<iostream>
 
using std::cout;
 
using std::cin;      

九、命名空間與重載

  • 1.重載與using聲明
  • using聲明時聲明的是一個名字,而非一個特定的函數
  • 該函數的所有版本都被引入到目前作用域中
  • 注意:如果using聲明的一個函數與作用域的一個函數同名且參數清單相同,将發生錯誤
using NS::print;//正确
 
using NS::print(int);//錯誤,不能指定參數清單      
  • 2.重載與using訓示
  • using訓示将空間内的所有函數都加載到重載集合中
  • 與using聲明不同的是:using訓示引入一個與作用域内函數名且參數清單相同的函數不會發生錯誤(但是我們要指明調用的是命名空間的還是目前作用域的)
namespace NS
 
{
 
extern void print(int);
 
extern void print(double);
 
}
 
void print(const std::string&);
 
using namespace NS;
 
int main()
 
{
 
print("Hello");//調用全局函數
 
print(10);//調用命名空間NS的
 
}