名前(識別子)が衝突する可能性を減らすため、名前があるものたちを分類し、分類自体にも名前を付けることで、おのおのを特定できるようにする機能です。
このページでは、プログラミングに限定して説明しますが、プログラミング以外の場面にも使われる概念で、目的は同じです。
変数や関数の名前はよく衝突します。たとえば、異なる処理に同じ名前がついてしまうことがあります(カードを引く draw と、描画の draw や、通信相手にデータを送り出す push と、スタックへの push のように)。
プログラミング言語によって仕様が異なるので、以下の例は架空のプログラミング言語による例です。
Card draw(); // カードを引く
void draw(); // 描画する
void push(data); // データを送信
void push(stack, data); // スタックへプッシュ
int main()
{
draw(); // どっち?
push("data"); // 引数の個数で分かるものの・・・
}
こういったとき、「何に対する」「何に属する」といったような情報を加えれば、それぞれの名前を大きく変えることなく、分かりやすく区別を付けることができます。
namespace card { // カード
Card draw(); // カードを引く
}
namespace graphics { // グラフィックス
void draw(); // 描画する
}
namespace network { // 通信
void push(data); // データを送信
}
namespace stack { // スタック
void push(stack, data); // スタックへプッシュ
}
int main()
{
graphics::draw(); // 明確
network::push("data"); // 明確
}
「draw」という名前に「graphics」を付加することで、グラフィックス機能の中に含まれる描画の関数のことを指していることが明確化できます。同様に、network::push
のような表記で、通信処理の中にある送信の関数であることを表しています。ここでの「graphics」や「network」が名前空間の名前であり、{
と }
で囲まれた範囲が名前空間です。
プログラミング言語によっては、名前空間の名前による指定を省略する機能や、名前空間に別名(エイリアス)を付ける機能を持っていることがあります。また、名前空間の入れ子を許す場合もあります。
C言語の仕様にも、名前空間という用語が登場します。
C言語においては、ラベル名、構造体などに付けるタグ名、構造体などのメンバ名、これら以外の名前、という4つの名前空間が設定されており、名前空間が異なっていれば、同じ名前を付けられます。
#include <stdio.h>
int main(void)
{
struct A { // タグ名
int A; // メンバ名
};
struct A A; // 変数名
.A = 10;
A
goto A;
.A = 20;
A
: // ラベル名
A("%d\n", A.A);
printf
return 0;
}
同じ名前空間の中で同じ名前を付けることはできません。そのため、C言語である程度の規模のプログラムを開発する場合には、名前の先頭に分類をあらわすプリフィックスを付けて対応することが多いです。
C++ には、名前空間を構築するためのキーワード namespace があります。
C++ の namespace についての解説が、C++編【言語解説】第3章にあります。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |