이번 항목의 네스티드라고 해서 무슨 말이지? 하고 잠깐 생각 했었다. 인터넷에서 검색을 해보니, "함수가 보이는 범위를 특정 함수안에서만 보이는 함수" 를 nested function 이라고 한다.

좀 생소한 느낌이 들었지만, 이런 기능이 C++ 에서도 있다는 것을 알게 되었다. 바로 클래스 내에 있는 클래스, 영어권에선 이런 클래스를 nested class 라고 한다. 우리나라에선 지역 클래스라고 하는거 같지만 이 책을 읽고 전혀 다른 의미인 것을 알게 되었다.

그렇다면 이번 항목의 주요한 질문은 무엇인가?


1. nested class는 무엇이며, 어떤 이유에서 유용하게 쓰일 수 있나?

우선 nested class 를 코드로 보여 준다면 아래와 같다.

여기에서 보듯이 OuterClass 의 내부에 NestedClass 가 보일 것이다. 이 NestedClass 를 nested class 라 부른다.  내 경우에는 이런 nested class 를 접근권환 제한을 걸 때 사용 한다. 즉 외부에 노출시키고 싶지 않은 클래스를 private 으로 설정해서 사용 한다.

요즘은 나의 경우에선.. 템플릿과 결합시켜서 include 관계를 없애버리기 위해서 사용 한다. 이 부분은 나중에 정리할 기회가 있따면 정리 하겠다. include를 안쓸순 없어도, 관계를 없앨 순 있다. C++ 사랑해!

이것은 절대 namespace 로 할 수 없는 것들이다..


2. local class 는 무엇이며, 어떤 이유에서 유용하게 쓰일 수 있나?

우선~ local class 를 코드로 보면

처럼 되어 있는 것을 볼 수 있다. 그렇다면 어디에 유용할까? .. 곰곰히 생각해 보면, 1번 질문의 유용성과 동일할 듯 싶다. f() 안에서만 LocalClass 가 보이기 때문이다.

단점이라면 local class 와 이름없는 class 의 경우 template 매개변수로 사용 할 수 없다. C++ 표준[C++98]의 섹션 14.3.1/2를 인용 한다면

지역 타입이나 연계(linkage)가 없는 타입, 이름이 없는 타입, 또는 위의 타입들이 합쳐져서 생긴 타입은 템플릿 타입 매개변수를 위한 템플릿-변수로 쓰여서는 안된다!


3. C++은 nested function 을 지원하지 않는다. 이것을 시뮬레이션 할 수 있는가?

... 함수 오브젝트 를 이용 하면 된다. 이거를 사용하기 위해서 책에선 매우 많은 페이지를 쓰고 있지만 함수 오브젝트가 무엇인지만 안다면 쉽게 이해가 될 것이다.

여기서 내가 집중적으로 생각했던 것은, "함수 자체는 객체로 봐도 무리가 없지 않을까?" 였다. 결론은 함수 자체를 객체로 볼 순 없다 였다. 왜냐하면 객체라면 내부의 상태를 가지고 있어야 된다고 생각하기 때문이다.

이런 내부의 상태를 가지는 함수는 C++에서 함수 오브젝트로 지원하고 있다. 이런 함수 오브젝트를 이용하면 충분히 nested function 을 시뮬레이션 할 수 있다. 왜냐하면 함수 객체가 다른 함수 객체를 이용하면 되기 때문이다.

자세한 설명은 링크로 대신 한다.


관련링크

Ask the C++ Pro 10-Minute Solutions <-- 영어를 못해서 소스 코드로...
Wikipedia : Function object <-- 역시 영어를 못해서 소스 코드로..

C++ 함수 객체(function object) <-- 우리나라 말.. 김윤수님 싸이트도 같이 링크 되어 있음


총평

지원하는 것과 사용할수 있는 것이 차이가 있듯이 조금 사용하기 불편한 감이 있지만, 애초에 C++로 nested function를 구현하는것이 목적이였으므로, .. 코드는 제외 한 것이었다. C++ 은 nested function 은 C++ 에선 불가능하다. 단지 구현 할 수만 있다.

가이드 라인에서 마지막으로 아래 한 문장으로 정리를 해 주었다.


"명료함을 추구한다, 복잡한 설계는 피한다, 애매함을 피해간다"


그렇다. ... 오캄의 면도날은 언제나 날카로운 것이다. 언젠가 소유하게된 오캄의 면도날, 조금씩 날카롭게 만들어가야 할 것 같다.



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

댓글을 달아 주세요