본문 바로가기
C++

[C++] 네임스페이스(Namespace)를 사용하는 이유

by 유노brain 2023. 10. 28.
반응형

네임스페이스(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"가 나오게 되는 것이지요.

반응형

댓글