More Exceptional C++ 의 7단원 "그 밖의 주제들" 은 대체로 난이도가 낮고, 많이 알려져 있는 사실들이 있어서, 술술 읽고 넘어간다. 이번 항목은 잘 사용하지 않았던 네임스페이스를 지금에서야 사용하면서 그 편리함에 탄복했던 나에게 절실히 필요했던 항목이기도 하다.

C++ 에서 컴파일러가 이름을 찾는 규칙에 대해서는 "The C++ Programming Language" 에서 자세히 나와 있어, 언제 기회가 생기면 정리하도록 하고, 우선 More Exceptional C++ 에서 나온 주제를 정리하도록 한다.

잠깐, 꼭 이름 찾기 규칙을 알고 넘어가야 할 것이다.


질문

using 선언과 using 지시자는 무엇이고, 어떻게 사용되는가? 둘 중 순서에 영향을 받는 것은?


해설

C++ 표준화 작업의 산물로 네임스페스는 아주 간편하면서 막강한 역활을 수행하게 되었는데, 바로 기존의 코드의 이름들의 중복을 피하고, 이름에 공간이라는 개념을 넣어, 표준화가 된 함수들을 std:: 안에 넣어 버려, 이름 충돌을 피하게 되는 역활을 충분히 수행했다는 점이다.


using 선언은 특정 네임스페이스에 있는 함수 또는 클래스를 현재 코드안에서 동일한 검색 대상 순위에 올려 주는 역활을 한다.

이 이야기에 대해서 참조를 하나 거는게 좋을듯 싶다.

참조
항목 31 : 이름 검색과 인터페이스 - 파트 1
http://www.ikpil.com/670

위의 참조로 위의 해설을 더 강하게 보충해 줄 수 있다. 그리고 네임스페이스와 "의존성" 이란 명제 아래 좀 더 생각해 볼것이 있으므로 참조를 통해 쭉 읽어보는게 도움이 될 듯 싶다.

Exceptional C++ 에서 설명하지 않았던 다른 주제는 using 선언의 순서에 따른 "보여짐"의 순서를 설명하는데, 다음 코드를 보자.


여기서 순차적으로 써져 있는 것을 유심히 보고 다음 코드에서 무엇이 호출 될지 예견해 보자.

보는거와 같이 5라인은 컴파일이 되지 않아 주석을 처리 했다. 어떤것이 호출 될지 예견해 보았는가? 이것은 using 선언의 순서가 그 만큼 중요 하다는 것을 보여준다.

위의 코드에 쓰여져 있는 모든것을 namespace A의 최초 정의 후 그 안에 X 크래스 int 를 반환하는 Y 함수, int 를 반환하며 double을 받아들이는 f함수를 정의한 후에 using 을 각각 선언해 끄집어 와서, 현재 지역안에서 위의 것들을 동등한 위치에서 검색하겠다고 컴파일러에게 알렸다.

그런 뒤 namcespace A를 추가(추가이다. 어디서든 추가할 수 있고 다른 파일에서도 추가 할 수 있다)하여 class Y 와 int f( int ) 를 정의 하였다.

이 과정을 거쳤을 때 int main() 에서 사용된 위의 코드를 예견해 봐야 할 것이다.

3 라인의 X x 는 컴파일러에게 A::X 의 객체 x를 선언하는 것으로 알렸으므로, 생성이 되지만,

5 라인의 Y y 는 컴파일러에게 A::Y 가 함수임을 using 통해 알려 두었으므로, 그 후에 추가된 Y 클래스의 객체 생성하라는것은 .. 문법 오류로 치부된다. 결국 컴파일 타임 에러 발생이다. 오로지 Y() 함수 호출로 A::Y() 만을 호출 할 수 있다, 동일한 네임스페이스 안에 다른 구역에 선언되어 있다면,( Y 함수 선언후 Y 클래스 선언) 결코 Y 클래스는 보이지 않는다. 오로지 그 어떠한 경우에도 Y 함수만 보인다.

7 라인의 f 는 3라인과 마찬가지로 먼저 using 으로 f의 이름이 지역과 동등한 위치에서 검색 되므로 위에 있는 f(double) 이 호출되어 진다.


이것은 헤더파일이 여러게 걸쳐서 namespace 를 사용 할 때, 같은 네임안에서의 네임충돌이 생길 수 잇는 점을 알려 준다. .. 같은 네임스페이스 같은 이름을 가진것을 만들기에는 그 확율이 적지만, .. 알고서 대처하는것과 모르고 대처하는것은 큰 차이기에 알고 넘어가야 될 것 같다.

마지막으로 using 지시자는 unsing namespace T; 를 뜻하는데, 해당 네임스페이스의 모든 것이 현재 지역의 공간에서 동등한 순위에서 검색하겟다고 컴파일러에게 알려 주는 것인데, 순서에 따른 "보여짐"은 위에서 설명한 것과 똑같이 영향을 받으니 고려해야 될 사항이다.


총평

간단하게 봤다가, .. 여러가지 실험을 해보게 만들었던 항목이였다. 이 항목을 공부하면서 느낀 것은, ... 어떠한 경우에서건 견고한 코딩을 위해선 "동일한 이름 자체를 피해야 한다" 로 결론이 내려지면서, #include 를 모두 다 한 후에 using 을 쓰거나, 한두개만 사용 되는 것이라면 아예 using 키워드를 사용하지 않는게 좋지 않을까 한다.

지금까지 namespace 로 지시한 것들속에 동일한 이름이 없어 이런 문제를 겪어 본적이 없으나, 필시 겪을 수 있는 경우가 있을 법 하다.

그러고 보니 "의존성" 이란 명제와 함께 생각한다면, 더 복잡해진다. .. 한가지를 알면 최소 10가지는 더 짚어봐야 하는 심오한 세계 C++ ..


신고
posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요

  1. Favicon of http://ikpil.com 게임 프로그래머라 불릴 최익필 2008.12.08 12:19 신고  Addr  Edit/Del  Reply

    어찌보면 완벽한 해결보다는 간접적으로 해결할 수 있음을 보여 주는 듯 하네요. 그래도 이거라도 얼마일까요? 없는 것 보단 좋다고 생각 합니다. : )