Cplusplus-cpp-namespaces
C ++の名前空間
同じクラスに同じ名前のZaraという2人の人物がいる場合を考えてみましょう。 彼らを明確に区別する必要があるときはいつでも、彼らが別の地域に住んでいるか、母親や父親の名前など、名前のような追加情報を使用する必要があります。
C ++アプリケーションでも同じ状況が発生する可能性があります。 たとえば、xyz()という関数を持つコードを記述している場合、同じ関数xyz()を持つ別のライブラリが利用可能です。 現在、コンパイラには、コード内で参照しているxyz()関数のバージョンを知る方法がありません。
- 名前空間*はこの困難を克服するように設計されており、同様の関数、クラス、変数などを区別するための追加情報として使用されます。 異なるライブラリで同じ名前が使用可能です。 名前空間を使用して、名前が定義されるコンテキストを定義できます。 本質的に、名前空間はスコープを定義します。
名前空間の定義
名前空間の定義は、次のようにキーワード namespace で始まり、その後に名前空間名が続きます-
namespace namespace_name {
//code declarations
}
関数または変数のいずれかの名前空間対応バージョンを呼び出すには、次のように名前空間名を追加します(::)
name::code; //code could be variable or function.
変数と関数を含むエンティティの名前空間のスコープを確認してみましょう-
#include <iostream>
using namespace std;
//first name space
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
}
//second name space
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
int main () {
//Calls function from first name space.
first_space::func();
//Calls function from second name space.
second_space::func();
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
Inside first_space
Inside second_space
usingディレクティブ
*using namespace* ディレクティブを使用して、名前空間の先頭に追加することを回避することもできます。 このディレクティブは、後続のコードが指定された名前空間の名前を使用していることをコンパイラーに伝えます。 したがって、名前空間は、次のコードのために暗示されています-
#include <iostream>
using namespace std;
//first name space
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
}
//second name space
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
using namespace first_space;
int main () {
//This calls function from first name space.
func();
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
Inside first_space
「using」ディレクティブは、名前空間内の特定のアイテムを参照するためにも使用できます。 たとえば、使用するstd名前空間の唯一の部分がcoutである場合、次のように参照できます-
using std::cout;
後続のコードは、名前空間を追加せずにcoutを参照できますが、 std 名前空間内の他の項目は、次のように明示的にする必要があります-
#include <iostream>
using std::cout;
int main () {
cout << "std::endl is used with std!" << std::endl;
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
std::endl is used with std!
*using* ディレクティブで導入された名前は、通常のスコープルールに従います。 この名前は、 *using* ディレクティブのポイントから、ディレクティブが見つかったスコープの終わりまで表示されます。 外部スコープで定義された同じ名前のエンティティは非表示になります。
不連続な名前空間
名前空間はいくつかの部分で定義できるため、名前空間は個別に定義された部分の合計で構成されます。 名前空間の個別の部分は、複数のファイルに分散できます。
そのため、名前空間の一部に別のファイルで定義された名前が必要な場合、その名前を宣言する必要があります。 次の名前空間の定義を書くことは、新しい名前空間を定義するか、既存の名前空間に新しい要素を追加します-
namespace namespace_name {
//code declarations
}
入れ子になった名前空間
名前空間は、次のように別の名前空間内の1つの名前空間を定義できるネストすることができます-
namespace namespace_name1 {
//code declarations
namespace namespace_name2 {
//code declarations
}
}
次のように解決演算子を使用して、ネストされた名前空間のメンバーにアクセスできます-
//to access members of namespace_name2
using namespace namespace_name1::namespace_name2;
//to access members of namespace:name1
using namespace namespace_name1;
上記のステートメントで、namespace_name1を使用している場合は、namespace_name2の要素を次のようにスコープで使用可能にします-
#include <iostream>
using namespace std;
//first name space
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
//second name space
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
}
using namespace first_space::second_space;
int main () {
//This calls function from second name space.
func();
return 0;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
Inside second_space