내가 C++에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve C++ 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다.  - 최익필


이번 항목은 "클래스 멤버 함수가 호환되는 모든 타입을 받아 들이기 위해선 템플릿을 사용하면 편하다" 를 주제로 이야기 한다.

템플릿의 특성은 "여러 타입의 변수에 있어 하나의 코드로 대응 시킬 수 있다" 이다. 이것은 "모든 타입"에 대해서 동일한 코드로 대응 시킬수 있다는 뜻인데.. 하필이면 "호환되는 모든 타입" 이다. 호환되는 모든 타입이라.. 무슨 뜻일까?

예제코드 1, 호환성이 이해가 될 것이다.


호환성이란, 서로 다른 타입이여도 대입과 참조가 가능한 성질을 뜻 한다.

자, 이제 항목 45의 제목을 다시 풀이해 보자.
호환이 안되는 타입은 받지 못하고, 오로지 호환되는 타입들의 모든 것을 받아 들이는데는 템플릿이 좋다! 로 해석이 된다.

어떻게 좋은지 설명이 필요할 것 같다. 대표적인 사례로 ... 역시나 스마트 포인터(Smart Pointer)가 제일 좋을 듯 싶다. .. 스마트 포인터(Samrt Pointer)에 대한 설명은 생략하고, 링크로 대신 한다.
링크 : http://lastmind.net/blog/2004/09/the-new-cpp-smart-pointers.html

왜 포인터냐 하면, .. 포인터야 말로 호환성으로 인한 참조가 가장 많이 벌어지기 때문이다. 그래서 Effective C++ 45 항목에서도 스마트 포인터를 든것 같다.

예제코드 1에서 상속 관계에 있는 객체의 호환성을 보여주는 부분을 기준으로 설명을 하겠다.
CBase 클래스와 CDerived 클래스 간의 계통에서 CBase * 나 &는 CDerived를 받을 수 있는 호환성이 있지만, CDerived * 나 &는 CBase를 받을 수 있는 호환성이 없다!

주제대로 이야기가 진행 된다면,
스마트 포인터가 CBase 형을 받는다면, 호환이 되는 CDerived 타입도 받아야 하며, 호환성이 없는 타입을 받지 말아야 한다.

어떻게 하면 그렇게 만들 수 있을까? 차근 차근 템플릿 부터 만든다면, 이렇게 만들 것이다.

컴파일 에러 나는 부위는 스마트 포인터로 이것 저것 하다가 생길 수 있다. 이때 스마트 포인터는 받아 드려야 하지만, 컴파일 에러가 나며, 당혹스럽게 만든다. 왜 .. 저런 에러가 났을까?

왜냐하면.. 서로다른 클래스이기 때문이다. 클래스 자체가 다르기 때문에, operator= 연산에서 서로 다른 타입이라 컴파일 될수 없다는 경고가 발생한다. 곰곰히 생각해 보면, 스마트 포인터 실체만 받아와서, 넘기면 바로 될것 같다. 그런데.. 그 스마트 포인터 타입이 한두개가 아닌데, 전부 다 미리 선언 할수도 없는 노릇이다. 그렇다!

다시 한번 주제를 생각해 보면, .. "호환되는 모든 타입을 받아 들이는데는 함수 템플릿이 직방!" 이다. 

oerpator= 을 멤버 함수 템플릿(member function template, 멤버 템플릿이라고도 함)으로 만들어서, 내부 데이터를 끄집어 오면 다 해결 될 것이다.

나도 위의 smart_ptr이 정신 나갔다는 것은 안다. 카운팅을 하지 않아. 메모리 누수가 발생하기 때문이다. 하지만 중점이 되었던 다른 타입의 smart_ptr을 문제 없이 잘 받아 지고 있는 것을 확인 할 수 있을 것이다.


이렇게 멤버 함수 템플릿(member function template)를 사용하면, 타입 호환성을 가진 모든 타입을 받을 수 있게 된다. (생성자나 기타 explicit 의 유무에 대해서 .. 좀더 고려 해야 할 것이다.)

그리고 위의 코드로 operator= 이나 생성자를 만들었어도, 컴파일러가 은밀히 만들어 주는 operator= 과 기본 생성자가 생기므로, .. 필히 직접 선언해 줘야 한다.


이것만은 잊지 말자.
1. 호환되는 모든 타입을 받아 들이는 멤버 함수를 만들려면 멤버 함수 템플릿을 사용하면 편하다.
2. 복사 생성자와 대입 연산자를 템플릿으로 만들었다면, 필히 직접 정의해 주는게 좋다.
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기