C++에서는 이미 정의된 네임스페이스를 나중에 다시 열어 멤버를 추가하는 방식으로 네임스페이스를 확장할 수 있으며, 이름이 없는 무명(익명) 네임스페이스를 사용하여 파일 내부에서만 접근 가능한 고유한 식별자를 선언할 수도 있습니다. 이번 글에서는 두 가지 기법을 예제와 함께 자세히 살펴보겠습니다.
네임스페이스 확장이란?
하나의 네임스페이스는 여러 번에 걸쳐 정의될 수 있습니다. 같은 이름의 네임스페이스 블록을 반복해서 작성하면, 컴파일러는 이들을 하나로 합쳐서 관리합니다. 첫 번째 정의에 어떤 멤버가 있고, 두 번째 정의에 다른 멤버가 있다면 결과적으로 해당 네임스페이스가 확장되며, 모든 멤버에 접근할 수 있게 됩니다.
예제 코드
#include <iostream>
using namespace std;
namespace my_namespace {
int my_var = 10;
}
namespace my_namespace { // 네임스페이스 확장
int my_new_var = 40;
}
main() {
cout << "my_var 값: " << my_namespace::my_var << endl;
cout << "my_new_var 값: " << my_namespace::my_new_var << endl;
}
실행 결과
my_var 값: 10
my_new_var 값: 40
위 예제처럼 my_namespace를 두 번 정의했지만, 실제로는 하나의 네임스페이스로 병합되어 my_var와 my_new_var 모두 ::(범위 지정 연산자)를 통해 접근할 수 있습니다. 이 방식은 헤더 파일과 소스 파일에 걸쳐 네임스페이스 멤버를 나누어 선언할 때 유용하게 활용됩니다.
무명(익명) 네임스페이스
무명 네임스페이스는 말 그대로 이름이 없는 네임스페이스입니다. 일반 네임스페이스와 달리 다음과 같은 특징을 가집니다.
- 동일한 파일(프로그램 단위) 내에서 직접 사용할 수 있습니다.
- 해당 파일 내부에서만 유효한 고유한 식별자를 선언하는 용도로 사용됩니다.
- 네임스페이스의 이름은 컴파일러가 자동으로 고유하게 생성합니다.
- 생성된 그 파일 안에서만 접근 가능하며, 외부 파일에서는 사용할 수 없습니다.
- 변수의
static선언을 대체하는 현대적인 방법으로 권장됩니다.
C++ 표준 위원회는 내부 링크(internal linkage)가 필요한 경우 static 키워드보다 무명 네임스페이스를 사용할 것을 권장하고 있으므로, 새로운 코드 작성 시에는 무명 네임스페이스를 사용하는 것이 좋습니다.
예제 코드
#include <iostream>
using namespace std;
namespace {
int my_var = 10;
}
main() {
cout << "my_var 값: " << my_var << endl;
}
실행 결과
my_var 값: 10
무명 네임스페이스의 멤버는 이름이 없기 때문에 범위 지정 연산자 없이 일반 변수처럼 곧바로 접근할 수 있습니다. 대신 다른 번역 단위(다른 소스 파일)에서는 참조할 수 없으므로, 전역 변수의 의도치 않은 노출을 막는 데 효과적입니다.