본문 바로가기

Effective C++/7. 템플릿과 일반화 프로그래밍

(4)
항목 44: 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 템플릿은 코딩 시간 절약, 코드 중복 회피의 두마리 토끼를 한꺼번에 잡아 준다. 하지만 아무 생각 없이 템플릿을 사용하면 코드 비대화(code bloat)가 나타날 수 있다. 이 코드 비대화를 어떻게 하면 방지할 수 있을까? 우선적으로 써 볼 수 있는 방법은, 공통성 및 가변성 분석(commonality and variability analysis)이다. 이름은 좀 거창해보이지만 사실 우리가 항상 해오던 분석 방법이다. 우리가 어떤 함수를 만들고 있다가 무심코 다른 함수를 봤는데, 지금 만들고 있는 함수 구현 중 일부가 다른 함수의 구현에도 똑같이 있다는 사실을 알아챘다고 가정해보자. 당연히 우리는 두 함수로부터 공통 코드를 뽑아내고, 이것을 별도의 새로운 함수에 넣은 후, 이 함수를 기존의 두 함수가 ..
항목 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자. 회사에서 메세지를 전송하는 프로그램을 만들고 있다고 가정해보자. 메세지는 암호회될 수도 있고, 비가공텍스트(비암호화) 형태가 될 수도 있다. 만약 어떤 메세지가 어떤 회사로 전송될지를 "컴파일 도중"에 결정할 수 있는 충분한 정보가 있다면, 주저 없이 템플릿 기반의 방법을 쓸 수 있을 것이다. 여기에 덧붙여서 메세지를 보낼 때마다 관련 정보를 로그로 남기고 싶다. 이럴땐 파생 클래스를 사용하면 쉽게 이 기능을 붙일 수 있다. 이 파생 클래스를 자세히 보면, 메시지 전송 함수의 이름(sendClearMsg)이 기본 클래스에 있는 것(sendClear)과 다르다는 것을 알 수 있다. 이러한 설계는 다음과 같은 장점을 가진다. 기본 클래스로부터 물려받은 이름을 파생 클래스에서 가리는 문제(항목 33 참고) 하..
항목 42: typename의 두 가지 의미를 제대로 파악하자 질문: 아래의 두 템플릿 선언문에 쓰인 class와 typename의 차이점이 뭘까요? 답변 : 차이가 없다! 템플릿의 타입 매개변수를 선언할 때는 class와 typename이 완전히 똑같다. 하지만 언제까지나 class와 typename이 똑같으면 이 둘을 구분할 이유가 없다. 이 둘이 다를 때가 언제인지 알아볼려면, 일단 템플릿 안에서 우리가 참조할 수 있는 이름의 종류가 2가지라는 것부터 알아야 한다. 함수 템플릿이 하나 있다고 가정하자. 이 템플릿은 STL과 호환되는 컨테이너를 받아드리도록 만들었고, 이 컨테이너에 담기는 객체는 int에 대입할 수 있다. 이 템플릿이 하는 일은 컨테이너에 담긴 원소들 중 두번째 것의 값을 출력하는 것이다. 여기서 지역변수 iter와 value에 강조 표시를 한다..
항목 41: 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타입 다형성부터 객체 지향 프로그래밍의 핵심 축은 다음과 같다. 명시적 인터페이스(explicit interface) 런타임 다형성(runtime polymorphism) 예를 들어 아래의 클래스와, 다음의 함수가 있다고 가정하면, doProcessing() 안에 있는 w에 대해 말할 수 있는 부분은 다음과 같다. w는 Widget 타입으로 선언되었기 때문에, w는 Widget 인터페이스를 지원해야 한다. Widget의 맴버 함수 중 몇 개는 가상 함수이므로, 이 가상 함수에 대한 호출은 런타임 다형성에 의해 이루어진다. 하지만 템플릿과 일반화 프로그래밍의 세계에서는 뿌리부터 뭔가 다른 부분이 있다. 명시적 인터페이스 및 런타임 다형성은 그대로 존재하지만 중요도가 떨어진다. 이 세계에서는 암시적 인터페이스(implici..