항목 35 : 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자
객체 지향 설계에 대한 여러 가지 방식을 학습해 봅시다.
비가상 인터페이스 관용구를 통한 템플릿 메서드 패턴
사용자로 하여금 public 비가상 멤버 함수를 통해 private 가상 함수를 간접적으로 호출하게 만드는 방법으로, 비가상 함수 인터페이스 관용구라고 많이 알려져 있습니다. 이 관용구는 템플릿 메서드라 불리는 디자인 패턴을 C++ 식으로 구현한 것입니다. 이 관용구에 쓰이는 비가상 함수를 가상 함수의 랩퍼라고 부르기도 합니다.
함수 포인터로 구현한 전략 패턴
가상 함수를 함수 포인터 데이터 멤버로 대체합니다 군더더기 없이 전략 패턴의 핵심만을 보여주는 형태입니다.
tr1::function으로 구현한 전략 패턴
가상 함수를 tr1::function 데이터 멤버로 대체하여 호환되는 시그너처를 가진 함수호출성 개체를 사용할 수 있도록 만듭니다. 이역시 전략 패턴의 한 형태입니다.
"고전적인" 전략 패턴
한쪽 클래스 계통에 속해 있는 가상 함수를 다른 쪽 계통에 속해 있는 가상 함수로 대체합니다. 전략 패턴의 전통적인 구현 형태입니다.
꼭 잊지 말아야 할 것!
1. 가상 함수 대신에 쓸 수 있는 다른 방법으로 NVI 관용구 및 전략 패턴을 들 수 있습니다. 이 중 NVI 관용구는 그 자체가 템플릿 메서드 패턴의 한 예입니다.
2. 객체에 필요한 기능을 멤버 함수로부터 클래스 외부의 비멤버 함수로 옮기면, 그 비멤버 함수는 그 클래스의 public 멤버가 아닌 것들을 접근할 수 없다는 단점이 생깁니다.
3. tr1::function 객체는 일반화된 함수 포인터처럼 동작합니다. 이 객체는 주어진 대상 시그너처와 호환되는 모든 함수호출성 개체를 지원합니다.
'언어 > C++' 카테고리의 다른 글
[Effective C++] 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자 (0) | 2020.02.06 |
---|---|
[Effective C++] 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! (0) | 2020.02.05 |
[Effective C++] 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 (0) | 2020.02.03 |
[Effective C++] 상속된 이름을 숨기는 일은 피하자 (0) | 2020.02.02 |
[Effective C++] public 상속 모형은 반드시 "is-a(...는 ...의 일종이다)"를 따르도록 만들자 (0) | 2020.02.01 |