C++のネーミングスペースnamespace



1つのエンタープライズクラスの開発では、1つのプロジェクトが大きくなり、定義されたクラスと方法も特に多くなり、サードパーティ製ライブラリも多く導入されます.これにより、同名の競合問題が避けられません.Javaにはパッケージ(Package)という概念があります.つまり、異なる機能のクラスを異なるパッケージに分けて名前の競合を解決し、C++ではネーミングスペースでこの競合を解決します. 
 
名前の競合とは
あなたのプログラムにサードパーティ製のライブラリがあるとします.lib、中にはグローバルな関数void HelloWorld()があります.また、自分のプロジェクトでHelloWorld()を再定義すると、名前の競合が発生します.
例えば、1つの大きい工事は複数の人が同時に開発して、一人一人が1つのモジュールを開発して、その中にAモジュールとBモジュールがそれぞれ甲、乙の2人が開発します.Aモジュールにstruct構造ノードがあると仮定し、Bモジュールにもstruct構造ノードがある.二人で開発したため、AのノードとBのノードは名前は同じだが構造は異なる.同じ役割ドメイン内に同じクラスが2つも存在しないため、A、Bの2つのモジュールにネーミングスペースがないと競合します.
このようにネーミング競合を引き起こすことは多く、要約すると、同じ役割ドメイン内に同じ名前のクラス、関数、変数が複数表示されます.
 
ネーミングスペースの定義
【例1】
 Hello.h
#pragma once

namespace SH
{
	class Hello
	{
	public:
		Hello(void);
		~Hello(void);

	public:
		void SayHello();

	};

	void HelloWord();
}

Hello.cpp
#include "StdAfx.h"
#include "Hello.h"
#include <iostream>

using std::cout;
using std::endl;

namespace SH
{
	Hello::Hello(void)
	{
	}


	Hello::~Hello(void)
	{
	}

	void Hello::SayHello()
	{
		cout << "how are you!" << endl;
	}

	void HelloWord()
	{
		cout << "Hello World!" << endl;
	}

}

Hello.cppは、以下のように定義することもできる.
 
SH::Hello::Hello(void)
{
}


SH::Hello::~Hello(void)
{
}

void SH::Hello::SayHello()
{
	cout << "how are you!" << endl;
}

void SH::HelloWord()
{
	cout << "Hello World!" << endl;
}

【例2】ネーミングスペースの定義は、以下のように不連続であってもよい.
Hello.h
#pragma once

namespace SH
{
	class Hello
	{
	public:
		Hello(void);
		~Hello(void);

	public:
		void SayHello();

	};

}

void HelloWord();

namespace SH
{
	void Hello2Sunly();
}

Hello.cpp
 
#include "StdAfx.h"
#include "Hello.h"
#include <iostream>

using std::cout;
using std::endl;


SH::Hello::Hello(void)
{
}


SH::Hello::~Hello(void)
{
}

void SH::Hello::SayHello()
{
	cout << "how are you!" << endl;
}

void HelloWord()
{
	cout << "Hello World!" << endl;
}

void SH::Hello2Sunly()
{
	cout << "Hello Sunly!" << endl;
}

上の例ではクラスHelloと関数Hello 2 Sunlyのネーミングスペースは同じで,いずれもSHである.HelloWordはSHネーミングスペースではなく、デフォルトのグローバルネーミングスペース内にあります.
 
 
ネームスペースの使用
ネーミングスペースの接頭辞と役割ドメイン演算付
 
#include "stdafx.h"
#include <iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;
	return 0;
}

この方法は、使用する各変数がネーミングスペースの接頭辞で特定のバージョンを示すため、最も安全です.しかし、使用するたびに接頭辞を付けるので面倒です.
using宣言
 
#include "stdafx.h"
#include <iostream>

using std::cout;
using std::endl;

int main()
{
	cout << "Hello World!" << endl;
	return 0;
}

どの変数が必要な場合にどの変数を宣言するかは、比較的安全で、あまり面倒ではなく、推奨される方法の1つです.USingで導入された変数は、その役割ドメインがusing指示からusing指示が存在する役割ドメインが終了するまで存在する.
using指示
 
#include "stdafx.h"
#include <iostream>
#include "Hello.h"

using namespace std;
using namespace SH;

int main()
{
	cout << "Hello World!" << endl;
	Hello2Sunly();
	return 0;
}

この方式はあるネーミング空間の下のすべての変数を注入し、この方式はプログラミングをより簡単にし、必要な変数を1つ1つusingで追加する必要はありませんが、再びネーミング衝突の危険をもたらしました.複数のネーミング空間が前の役割ドメインの下で、また重名の問題が発生する可能性があるからです.