C++之命名空間,命名空間
C中是沒有命名空間這個概念的,是C++中新引入的一個東西,為了處理同名的衝突。
其實命名空間就是封裝的一個概念。把一些變數、函數、類給封裝起來。和類的封裝概念很像,但是比類的封裝要大。
一、淺析
1. 自訂定義命名空間
格式:Namespacename{}
namespace my{ int i=2; void foo() {cout<<"my:"<<i<<endl;}}namespaceyour{ class A{};}
2. 使用命名空間中的東西(3種方法)
namespace my{ int i=2; void foo() {cout<<"my:"<<i<<endl;}}
(1)using namespace my; 之後的程式就可以使用my中的所有東西(i和foo())
using namespace my;int _tmain(int argc, _TCHAR* argv[]){ foo();//OK cout<<i<<endl;//OK system("pause"); return 0;}
(2)using my::foo,之後的程式就可以使用my中foo了。
using my::foo;int _tmain(int argc, _TCHAR* argv[]){ foo();//OK cout<<i<<endl;//ERROR system("pause"); return 0;}
(3)程式中直接使用my::i和my::foo()
int _tmain(int argc, _TCHAR* argv[]){ my::foo();//OK cout<<my::i<<endl;//OK system("pause"); return 0;}
思考:其實命名空間和類的封裝很像。一個命名空間裡想要使用另一個命名空間裡的東西,必須using或命名空間::。
二、深析
1. 定義命名空間
命名空間是跨檔案的。也就是說可以在多個cpp檔案中定義同一命名空間,這樣的作用就是可以往已存在的命名空間中加入東西。
namespacestd{
int i=2;
}
此代碼的目的就是想往命名空間std加入變數i。(雖然很不提倡,但無語法錯誤)
其實C++標準庫也是這麼做的。因為標準庫中一個命名空間包含的函數或類是很多的,不可能把這些函數、類都寫在一個cpp檔案中。所以利用不斷往一個命名空間加入東西來形成完整的標準庫的命名空間。
2. 使用命名空間
前面提到的使用命名空間中東西,的前提是該命名空間的定義已經在本cpp中,如果不存在,需要#include把要使用的命名空間的定義include進來。例如:inlcude<iostream>usingnamespace std;
看到這裡引出另一個問題:
C中的#include<xxx.h>和C++中的#include<xxx> using namespace xxx的區別?
其實這2個語句都是想要使用xxx中的東西。C中沒有命名空間這個概念,所以不需要namespace。而C++中,標準庫的函數都是放在某一命名空間中的,所以必須要有using namespace xxx;
也就是說iostream中的各種函數都是在std中的,顯然std還包括其他很多東西。
思考:為何C++要把include<xxx.h>中的.h給去掉?
因為我們在寫C++程式時,有時會把類的定義寫在.h檔案中,而把類的實現放在cpp檔案中。
//t.hclass A{public:void foo();};
//t.cpp#include "stdafx.h"#include<iostream>using namespace std;#include "t.h"void A::foo(){ cout<<"print"<<endl;}int _tmain(int argc, _TCHAR* argv[]){ A a; a.foo(); system("pause"); return 0;}
這裡在t.cpp中,我們#include”t.h”,我們只是想要類A的定義式。
而上面我們講到,C++中的#include<xxx>我們是想要使用xxx裡面的東西。顯然xxx中肯定不只是定義式,而且必須是已經實現了的。
所以這裡C++這個改動目的就是為了區別xxx和xxx.h。xxx裡是已經定義且實現好了的東西。而xxx.h可以是只是定義式。
所以我們只要見到xxx,就能確定它是定義實現了的。而見到xxx.h,它可能只是定義式。
3. include的本質含義
很簡單,就是把include後面的檔案放到本檔案中進行編譯執行。
4. global namespace
C++中任何一段代碼都在某個命名空間。所有沒有定義命名空間的,C++預設是都屬於global namespace。注意global namespace和其他的命名空間本質上是沒有區別的。
namespace my{int i=1;}int i=2;using namespace my;int _tmain(int argc, _TCHAR* argv[]){ i=3;//ERROR system("pause"); return 0;}
由於i=2是沒有定義命名空間,屬於global namespace。而using namespace my,所以下面的main是在global namspace中的,所以可以使用globalnamespace,也可以使用my namespace。而由於兩個命名空間都有i,所以系統不知道該調用哪個,就會出錯。
5. 無名命名空間
namespace {
int i=1;
}
顯然無法被別的檔案使用。它只是在本檔案中可以被有效使用。注意和globalnamespace的區別。
6. 不要給C++中的標準庫加入任何東西
例如上面的1提到的:
namespacestd{
int i=2;
}
如果這段代碼被別的程式引用,雖然這段代碼不會出現編譯、運行錯誤。但是在C++中有可能會出現不明確的行為,有時會出現莫名其妙的東西。所以一定不要加。
7. 嵌套命名空間
namespacensl
{ const int RATE=0.08; //常量
double pay; //變數
double tax() //函數
{return 1.2*RATE;}
namespace ns2 //嵌套的命名空間
{int age;}
}
如果想輸出命名空間nsl中成員的資料,可以採用下面的方法:
cout<<nsl::RATE<<endl;
cout<<nsl::pay<<endl;
cout<<nsl::tax()<<endl;
cout<<nsl::ns2::age<<endl; //需要指定外層的和內層的命名中間名
有關命名空間
大多數 C# 應用程式從一個 using 指令節開始。該節列出應用程式將會頻繁使用的命名空間,避免程式員在每次使用其中包含的方法時都要指定完整名稱。
樣本
using System;
class Hello
{
static void Main()
{
Console.WriteLine("Hello World!");
}
}
說明:
在訪問命名空間時,要使用using指令進行指定並且放在程式的開頭,如果不在第一行指定命名空間,在輸出語句中就必須書寫命名空間的名稱。
例如:
class Hello
{
static void Main()
{
System.Console.WriteLine("Hello World!");
}
}
★ 命名空間別名
從上面的樣本中我們學會了使用using指令為程式指定要使用的命名空間,除此以外using指令還有一個功能,就是建立命名空間別名而引用命名空間,其格式如下:
using 別名 = 命名空間
using 別名 = 命名空間.類名
樣本
現在我們為System.Console起一個別名,假如叫做Alias,則程式可以寫為如下形式:
using Alias = System.Console;
class Hello
{
static void Main()
{
Alias.WriteLine("Hello World!");
}
}
★ 自訂命名空間
除了上面使用 using 指定使用內建命名空間外,在較大的編程項目中,聲明自己的命名空間可以協助控制類名稱和方法名稱的範圍。命名空間聲明使用namespace關鍵字,格式如下所示:
namespace 名稱
{
型別宣告
}
樣本
namespace SampleNamespace
{
class SampleClass
{
public void SampleMethod()
{
System.Console.WriteLine("SampleNamespace");
}
}
}
★ 命名空間嵌套
實際上命名空間是用來表示一個範圍的。在項目中建立範圍的能力有助於組織代碼,並提供建立全域唯一的類型的途徑。
樣本
樣本中名為 myClass 的類在兩個命名空間中定義,其中一個命名空間嵌套在另一個之內。. 運算子用於區分所調用的方法。
namespace N1
{
class myClass
{
public void SampleMethod()
{
System.Console.WriteLine("SampleMethod1");
}
}
namespace N2
{
class myClass
{
public void SampleMethod()
{
System.Console.WriteLine("SampleMethod2"......餘下全文>>
c語言關鍵詞using namespace意思
這是C++才會有的語言特性.
假如你使用一個程式庫,他裡面有桓霰淞拷衋bc,但是你自己也不小心定義了一個叫abc的變數,這樣就會引起重定義錯誤.所以為了避免這種現象,C++引入了名字空間(namespace)的概念,編寫程式庫的時候最好把所有東西放在一個namespace中,例如
namespace MY
{
int abc;
char cab;
}
這樣,你在外界就要通過MY::abc來訪問MY裡面的abc,而如果你自己在外面定義了一個叫abc的變數,不會引起重定義的錯誤.直接調用abc會調用你自己定義的abc,而只有用MY:abc才會真正調用出MY裡面的abc
但是這樣未免太麻煩,如果你確保你不會重複使用別人程式庫裡的名字,你就可以把他的名字空間裡所有名字全部調出,這個過程就是using namespace,例如我輸入
using namespace MY;
這樣,下面我再調用abc時,就會自動調用MY裡面的abc了.