네임스페이스(Namespace)
네임스페이스는 특정한 식별자(함수, 변수, 클래스)를 포함하는 코드지역을 뜻합니다.
C++에서는 같은 식별자를 여러 번 선언/정의할 수 없습니다.
그렇지만 우리가 식별자를 여러번 사용하고 싶을 때가 있는데요.
네임스페이스는 식별자를 여러번 선언/정의하는 것을 허용합니다.
네임스페이스는 특정한 식별자를 가져야 합니다.
하지만, 식별자는 네임스페이스 전체에서 동일한 이름을 가질 수 있습니다.
★ main 함수는 네임스페이스가 될 수 없습니다. ★
아래 예시코드를 보면서 더 구체적으로 설명하겠습니다.
예시코드
#include <iostream>
namespace ns1{
int value = 3;
}
namespace ns2{
std::string value("Hello World");
}
int main(){
std::cout<<ns1::value<<std::endl;
std::cout<<ns2::value<<std::endl;
}
위의 코드에서 ns1는 ns1 지역 안에서 value = 3이 선언되었습니다.
마찬가지로 ns2는 ns2 지역 안에서 "Hello World"를 선언하였습니다.
그렇기 때문에
main함수에서 ns1::value는 ns1지역 안에 있는 value를 가져오게 됩니다.
ns2::value는 ns2지역 안에 있는 value를 가져오게 됩니다.
네임스페이스 둥지
네임스페이스 둥지(Nested namespaces)에 대해 말씀드리겠습니다.
네임스페이스 안에 네임스페이스가 있는 것을 Nested namesapces라고 합니다.
예시코드를 보며 설명하겠습니다.
예시코드
#include <iostream>
namespace ns1{
void foo(){
std::cout<<"foo() in ns1" << std::endl;
}
namespace ns2{
void foo(){
std::cout<<"foo() in ns2" << std::endl;
}
namespace ns3{
void foo(){
std::cout<<"foo() in ns3" << std::endl;
}
}
}
namespace ns4{
void foo(){
std::cout<<"foo() in ns4" << std::endl;
}
}
}
int main(){
ns1::foo();
ns1::ns2::foo();
ns1::ns2::ns3::foo();
ns1::ns4::foo();
}
위의 코드를 보면 네임스페이스 ns1안에 ns2, ns4가 있습니다.
ns2안에 ns3가 있습니다.
즉 ns3를 접근하기 위해서는 ns1안에 ns2안에 ns3가 있기 때문에 이 경로로 가져와야 합니다.
즉 ns1::ns2::ns3::foo() 로 접근해야 합니다.
네임스페이스 정의 분리
같은 네임스페이스는 몇 번이나 정의할 수 있습니다.
다음 아래와 같이 사용할 수 있습니다.
예시코드
#include <iostream>
namespace ns1{
void foo(){
std::cout << "foo() in ns1"<<std::endl;
}
}
namespace ns1 {
void bar(){
std::cout<< "bar() in ns1" << std::endl;
}
}
int main(){
ns1::foo();
ns1::bar();
}
네임스페이스 해결 규칙
컴파일러는 다음과 같이 네임스페이스의 식별자를 반복적으로 확인합니다.
-> 현재 네임스페이스에서 식별자를 찾습니다.
-> 만약에 없으면 외부 네임스페이스로 나가 찾습니다.
예시코드
#include <iostream>
namespace ns1{
std::string x = "ns1";
namespace ns2{
std::string x = "ns2";
namespace ns3{
std::string x = "ns3";
void foo(){
std::cout << x << std::endl;
}
}
}
namespace ns4{
std::string x = "ns4";
}
}
int main(){
ns1::ns2::ns3::foo();
}
위의 코드를 보면 x는 같은 네임스페이스 n3에 "n3"가 있으므로 "n3"를 출력하게 됩니다.
#include <iostream>
namespace ns1{
std::string x = "ns1";
namespace ns2{
std::string x = "ns2";
namespace ns3{
// std::string x = "ns3";
void foo(){
std::cout << x << std::endl;
}
}
}
namespace ns4{
std::string x = "ns4";
}
}
int main(){
ns1::ns2::ns3::foo();
}
만약 std::string x = "n3"을 주석처리한다고 하면 어떻게 될까요?
바로 위에서 말했듯이 외부 네임스페이스로 나아갑니다.
그러면 ns3 밖에 있는 ns2가 되게 됩니다.
그렇기 때문에 위의 답은 "ns2"가 됩니다.
#include <iostream>
namespace ns1{
std::string x = "ns1";
namespace ns2{
// std::string x = "ns2";
namespace ns3{
// std::string x = "ns3";
void foo(){
std::cout << x << std::endl;
}
}
}
namespace ns4{
std::string x = "ns4";
}
}
int main(){
ns1::ns2::ns3::foo();
}
만약 ns2마저 주석처리가 된다면 어떻게 될까요?
ns2마저 주석처리가 된다면 상위 네임스페이스로 가게 됩니다.
즉 "ns1"으로 나오게 됩니다.
#include <iostream>
namespace ns1{
std::string x = "ns1";
namespace ns4{
std::string x = "ns4";
}
namespace ns2{
std::string x = "ns2";
namespace ns3{
std::string x = "ns3";
void foo(){
std::cout << ns4::x << std::endl;
}
}
}
namespace ns4{
std::string x = "ns4";
}
}
int main(){
ns1::ns2::ns3::foo();
}
만약 ns4::x가 된다면 어떻게 될까요?
바로 외부스페이스에서 ns4를 찾아 ns4::x를 출력하게 됩니다.
즉 "ns4"가 나오게 되는 것이지요.
댓글