상속 경계

상속: 재사용 문법이 아니라 대체 가능성 선언

파생 클래스는 기반 클래스가 필요한 자리에 들어간다. 이 대체가 호출자 관점에서 참이 아니면 상속 계층은 코드 공유보다 큰 결합을 만든다.

01

계약을 좁히지 않는다

파생 클래스가 기반 함수의 사전 조건을 더 강하게 만들면 기반 타입 대체가 깨진다.

02

삭제 경로 확인

Base*로 Derived를 소유할 수 있으면 기반 소멸자는 virtual이어야 한다.

03

합성과 비교한다

공통 코드 몇 줄을 공유하려는 목적이면 멤버 객체 위임이 더 단순할 수 있다.

public
대체 가능성 외부 API에서도 Derived는 Base처럼 쓰일 수 있다.
가장 강한 약속이다.
protected
구현 공유 외부 대체 가능성보다 내부 재사용에 가깝다.
합성과 비교한다.
virtual dtor
다형 삭제 기반 포인터로 삭제할 때 파생 소멸자를 호출한다.
인터페이스 클래스의 기본값이다.
slicing
값 전달 손실 Derived를 Base 값으로 복사하면 파생 부분이 잘린다.
참조나 포인터를 쓴다.

대체 · 소멸 · 재사용 점검

대체 기반 타입을 받는 기존 코드가 파생 타입에서도 같은 의미로 작동하는가.
소멸 다형 객체를 소유한다면 virtual destructor가 있는가.
재사용 상속 없이 멤버 객체로 같은 구현을 공유할 수 있는가.

작은 기반 계약

class Renderer {
public:
    virtual ~Renderer() = default;
    virtual void render(const Scene&) = 0;
};