Namespace
< 위키피디아 [1] >
네임스페이스를 굳이 번역하자면 ‘이름 공간’으로,
개체를 구분할 수 있는 범위를 나타내는 말로, 일반적으로 하나의 네임스페이스에서는 하나의 이름이 단 하나의 개체만을 가리킨다. [1]
namespace Box1{ int boxSide = 4; } namespace Box2{ int boxSide = 12; } int main () { cout << Box1::boxSide << endl; //output 4 cout << Box2::boxSide << endl; //output 12 return 0; } |
< More Effective C++ [2] >
전역 유효범위에서 선언할 수 있는 것이면, 모두 네임스페이스 안에서 선언할 수 있다. 클래스, 구조체, 함수, 변수, 객체, typedef 타입 등.
네임스페이스란 쉽게 말해, 어떤 타입의 이름 충돌을 막는 상위 개념의 범주이다.
똑같은 김씨라도 김해 김씨와 안동 김씨가 다른 것처럼 네임스페이스는 이렇게 ‘김해’나 ‘안동’의 역할을 해준다고 보면 된다.
문법적으로 볼 때, 네임스페이스는 클래스와 아주 흡사하다. 그렇지만, public, protected, priavate같은 구분이 들어가지 않는다. 왜냐하면 네임스페이스 안의 모든 것이 public이니까.
네임스페이스를 일일이 치기 귀찮으면, 이렇게 using 선언을 통해 손가락의 힘을 아낄 수 있다.
: using namespace Box1;
그리고 PrintingStuff 네임스페이스에 thePrinter 클래스가 있으면 아래와 같이..
using namespace PrintingStuff::thePrinter;;
이 코드에는 기억해두면 피가 되고 살이 되는 미묘한 특징이 2개나 숨어 있다.
1. Printer 객체가 클래스의 정적 객체가 아니라 함수의 정적 객체라는 점~
클래스의 정적 멤버로 선언된 객체는 그것이 사용되든 사용되지 않든 상관 없이 생성된다. 이와 대조적으로, 함수 안에서 정적 변수로 선언된 객체는 그 함수가 최소한 한 번 호출되어야 생성된다. (‘쓰지 않는 것에는 값을 지불할 필요가 없다’라는 C++의 철학이 담겨 있다!)
2. 객체 초기화 시점을 정확히 알 수 있다는 점~
객체를 클래스의 정적 멤버로 정의하는 것이 나쁜 이유는 그 초기화 시점이 정확하게 정의되어 있지 않다는 점이다. C++은 하나의 컴파일 단위 안에 선언된 객체들의 초기화 순서는 엄격하게 보장하는 반면, 서로 다른 컴파일 단위마다 뿔뿔이 흩어진 정적 객체의 초기화 순서에 대해서는 일언반구도 언급하지 않았다.
그러나, 함수에 정적 객체(네임스페이스 안에 선언된 객체)는 그 함수가 처음 호출되어 그 정적 객체가 정의된 줄이 한 번 실행되었을 때 객체 초기화가 이루어진다.
< google c++ code style [3] >
구글 C++ 코딩 스타일을 보면,
네임스페이스는 .cpp(.cc) 파일 안에서 unnamed namespace(이름 없는 네임스페이스) 사용을 권장하고 있으며, 이름 있는 네임스페이스를 사용할 때는 프로젝트에 기반한 이름을 사용하도록 하고 있다. 또한 using 명령어를 사용하지 말라고 한다.
(이건 코딩 스타일이니 각자 알아서…; )
‘이름 없는 네임스페이스’는 .cpp(.cc)파일에서 선언하여 해당 파일에서만 유효하고 밖으로 노출되지 않기 때문이다.
‘이름없는 네임스페이스’는 static 변수/함수를 사용할 자리에 사용하면 좋다.
마지막으로, 특정 클래스와 관련된 file-scope 선언이 필요할 때는, ‘이름 없는 네임스페이스’보다 그 클래스의 정적(static) 멤버 변수/함수를 사용하는 것이 낫다.
참조
1. http://ko.wikipedia.org/wiki/%EC%9D%B4%EB%A6%84%EA%B3%B5%EA%B0%84
2. More Effective C++, p197
3. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces