1. 네임스페이스(namespace)

네임스페이스(namespace)란 뭘까요? 이름 공간? 이 네임스페이스에 대해 알아보기 전에, 간단한 예를 하나 들어보겠습니다. 


약 10명 정도의 개발자가 A, B라는 팀으로 나누어 어떤 팀 프로젝트를 진행한다고 가정해봅시다. 이렇게 팀을 나누어 개발이 모두 끝나면, 팀 A와 B가 개발한 프로젝트를 하나로 합친다고 해봅시다. 그렇게 해서 프로젝트를 합치고, 모든 일이 만사천리로 해결되는 듯 하였으나 A에서 정의한 함수의 이름과 B에서 정의한 함수의 이름 상당수가 동일하여 충돌이 일어나는 것이었습니다.


A.h:

...
namespace A {
	void doSomething(void) {
		// 코드...
	}
};
...

B.h:

...
namespace B {
	void doSomething(void) {
		// 코드...
	}
};
...

위의 문제를 해결하기 위해선 어떻게 해야 할까요? 바로 지금 배우게 될 '네임스페이스(namespace)'란 녀석으로 이름충돌을 미연에 방지할 수 있습니다. 네임스페이스를 간단히 말하면, 관련있는 녀석끼리 모여있는 공간을 말합니다. 아래의 예를 한번 보시죠.

#include <iostream>

namespace A {
	void Add() {
		printf("A의 Add() 호출!\n");
	}
}

namespace B {
	void Add() {
		printf("B의 Add() 호출!\n");
	}
}

int main()
{
	A::Add();
	B::Add();
	return 0;
}

결과:

A의 Add() 호출!
B의 Add() 호출!
계속하려면 아무 키나 누르십시오 . . .

코드를 보시면, 3행에서 A라는 네임스페이스가 등장했습니다. 이 네임스페이스 안에는 Add란 함수가 정의되어 있습니다. 9행을 보시면 똑같이 B라는 네임스페이스가 등장하고, 그 안을 보시면 여기에도 Add란 함수가 정의되어 있습니다. 그럼 이렇게 이름이 같은 함수를 어떻게 호출하는지 보도록 합시다. 좀더 내려가서, 17~18행을 보시면 :: 연산자로 앞에 있는 네임스페이스를 가르켜 그 안에있는 Add 메소드를 호출합니다. 여기서 :: 연산자는 '범위 지정 연산자'라는 것으로, 어떠한 네임스페이스를 가리킬때 사용하는 연산자입니다.


위에서 알게된 내용을 정리해보자면, 이렇습니다. 네임스페이스를 만드는 방법은 아래와 같습니다.

namespace 이름
{
   // 변수, 함수 등
}

그리고 네임스페이스 내에 있는 변수 혹은 함수 등을 사용하는 방법은 아래와 같습니다.

..
이름::함수명();
이름::식별자 = 10;

이번에는 using이란 녀석을 살펴보도록 하겠습니다.

2. using

이 using이란 녀석은, 네임스페이스를 쉽게 사용할수 있도록 도와주는 역할을 합니다. using에는 지시자와 선언자가 있습니다. 예를 들어서, 우리가 네임스페이스를 사용하며 네임스페이스 내에 있는 함수를 빈번하게 호출할 경우 네임스페이스명과 범위 지정 연산자를 추가로 적어야하므로 여간 귀찮은게 아닙니다. 그냥 함수 이름만 써놓고, '이 함수를 호출할때는 어느 네임스페이스 내에 있는 함수를 호출하겠다'라고 해두면 얼마나 좋을까요? 이런 문제를 바로 using이란 녀석이 해결합니다. 아래의 예제를 한번 봅시다.

#include <iostream>

namespace A {
	void Add() {
		printf("A의 Add() 호출!\n");
	}
	void Minus() {
		printf("A의 Minus() 호출!\n");
	}
}

using namespace A;

int main()
{
	Add();
	Minus();
	return 0;
}

결과:

A의 Add() 호출!
A의 Minus() 호출!
계속하려면 아무 키나 누르십시오 . . .

코드의 12행을 보시면, using 지시자가 등장했습니다. 이것은 A라는 네임스페이스를 명시적으로 사용하겠다는 말입니다. 이렇게 되면, 더이상 귀찮게 네임스페이스명을 붙일 필요가 없습니다. 네임스페이스 전체를 가져온 셈이 되는거죠. 이번에는 using 선언을 보도록 할까요?

#include <iostream>

namespace A {
	void Add() {
		printf("A의 Add() 호출!\n");
	}
	void Minus() {
		printf("A의 Minus() 호출!\n");
	}
}

using A::Add;

int main()
{
	Add();
	A::Minus();
	return 0;
}

결과:

A의 Add() 호출!

A의 Minus() 호출!

계속하려면 아무 키나 누르십시오 . . .

다시 12행을 보시면 이번에는 A에 있는 Add라는 함수만 사용하도록 명시해두었습니다. 이 상태에서 Minus에 A::를 제외시키면, 당연히 컴파일 오류가 뜹니다. (Add가 등장하면 네임스페이스 A의 Add 함수를 호출합니다.) 참고로 네임스페이스에 있는 함수와 이미 영역에 존재하는 함수의 이름이 겹치면 충돌한다는 것을 기억해두시기 바랍니다.


이번 네임스페이스(namespace)에 대한 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.


다음 강좌에서는 함수 오버로딩(Function Overloading)에 대해 알아보도록 하겠습니다.