名稱空間(Namespace)


隨著程式碼撰寫越來越多,程式內容越來越大,您會發現管理程式中的變數名稱、函式名稱、類別名稱也會是一件麻煩的事,尤其是一些同名問題的發生,例如在程 式中,您也許會定義一個Point類別代表2維空間的點,也許在程式的某個地方,您也會定義一個Point類別來表示一個3維空間的點,其它像函式同名、 共用變數同名的情況也可能發生,當這種情況發生時,其中一個定義就可能將另一個定義給覆寫掉了。

C++提供名稱空間的概念,它就像是一個管理容器,可以將您所定義的名稱區域在名稱空間之下,而不會有相互衝突的發生,例如您定義了一個 dimension2d與dimension3d的名稱空間,在它們之下都有一個Point類別,但由於屬於不同的名稱空間,所以這兩個名稱並不會有所衝 突。

C++使用"namespace"關鍵字來定義一個名稱空間,其語法如下所示:
namespace 名稱 {
    // 類別、函式或變數宣告
};

一個例子如下所示:
  • Point2D.h
namespace d2d { 
int i, j, k;

class Point2D {
public:
Point2D() {
_x = 0;
_y = 0;
}

Point2D(int x, int y) : _x(x), _y(y) {
}

int x() {return _x;}
int y() {return _y;}

private:
int _x;
int _y;
};
};

在名稱空間中的成員,可以直接使用當中所宣告的識別字,但如果您要在名稱空間之外使用這些成員,則要使用範圍解析運算子::,例如d2d:: Point2D,您要指明要使用哪一個名稱空間下的哪個類別,下面這個程式提供一個簡單的示範:
  • main.cpp
#include <iostream> 
#include "Point2D.h"
using namespace std;

int main() {
d2d::Point2D p1(10, 10);

cout << "(x , y) : ("
<< p1.x() << ", "
<< p1.y() << ")"
<< endl;

return 0;
}

執行結果:
(x , y) : (10, 10)

當然每次若都要使用範圍解析運算子來指明使用哪個名稱空間下的成員,也是相當麻煩,您可以使用"using"關鍵字指明所要使用的名稱空間或其下的成員, 則被指定的名稱空間或其下的成員就可以直接被使用,"using"有兩種用法,如下所示:
using 名稱空間::成員
using namespace 名稱空間

一個例子如下所示:
  • main.cpp
#include <iostream> 
#include "Point.h"
using namespace std;
using d2d::Point2D;

int main() {
Point2D p1(10, 10);

cout << "(x , y) : ("
<< p1.x() << ", "
<< p1.y() << ")"
<< endl;

return 0;
}

這個程式的執行結果與上一個相同;如果您確定將使用某個名稱空間下的所有類別,則可以使用第二種方式來指定名稱空間,例如:
  • main.cpp
#include <iostream> 
#include "Point.h"
using namespace std;
using namespace d2d;

int main() {
Point2D p1(10, 10);

cout << "(x , y) : ("
<< p1.x() << ", "
<< p1.y() << ")"
<< endl;

return 0;
}

C++的標準函式庫皆定義在std名稱空間中,這也就是為什麼每次在撰寫程式時,總會在檔案的最前頭加上using namespace std;的原因。

您還可以定義一種未命名的名稱空間,這可以建立唯一的識別字,只允許您在同一個檔案中使用這些識別字,例如:

namespace { 
int i, j, k;

class Point2D {
public:
Point2D() {
_x = 0;
_y = 0;
}

Point2D(int x, int y) : _x(x), _y(y) {
}

int x() {return _x;}
int y() {return _y;}

private:
int _x;
int _y;
};
};

如果在檔案中如上宣告,則i, j, k, Point2D等都只限於該檔案中使用,在其它檔案中就無法使用這些識別字。