Polymorphism

가상 함수 호출

다형성은 같은 메시지를 서로 다른 객체가 다르게 처리하게 만든다. 포인터나 참조로 접근할 때 override, 수명, 비용을 함께 점검해야 한다.

01

기반 계약을 쓴다

호출자는 구체 타입을 모르고도 의미 있는 함수를 호출할 수 있어야 한다.

02

파생 행동을 덮는다

override를 붙여 오타, const 누락, 인자 타입 차이를 컴파일 단계에서 잡는다.

03

소유권 결정

polymorphic object를 누가 만들고 누가 지우는지 unique_ptr<Base> 같은 타입으로 표현한다.

virtual
런타임 선택 기반 포인터 또는 참조로 호출할 때 실제 객체의 함수가 선택된다.
생성자와 소멸자 중 가상 호출은 기대와 다르다.
override
서명 검증 기반 함수와 정확히 같은 오버라이드인지 컴파일러가 확인한다.
서명 실수를 컴파일 단계에서 잡는다.
final
확장 차단 더 이상 파생되면 안 되는 클래스나 함수를 명시한다.
성능 힌트가 되기도 한다.
비용
간접 호출 가상 호출은 인라이닝과 branch prediction에 영향을 줄 수 있다.
핫패스는 측정 후 결정한다.

서명 · 수명 · 과설계 점검

서명 override가 없어서 새 함수를 만든 실수가 남아 있지 않은가.
수명 기반 타입으로 소유한다면 virtual destructor가 있는가.
과설계 실제 변형이 두세 개도 없는데 상속 계층을 먼저 만들고 있지 않은가.

override 확인

class ConsoleLogger : public Logger {
public:
    void write(std::string_view line) override;
        overflow-wrap: break-word;
        word-break: keep-all;
      };