Inheritance

상속은 코드 재사용보다 대체 가능성 검사가 먼저다

상속을 쓰면 파생 객체가 기반 객체가 필요한 자리에 들어간다. 이 관계가 의미적으로 참인지 확인하지 않으면 재사용보다 결합 비용이 커진다.

01

대체 가능성을 묻는다

기반 타입을 받는 모든 함수가 파생 타입에서도 같은 약속을 지키는지 확인한다.

02

수명 경로 검토

base pointer로 delete할 일이 있으면 기반 소멸자가 virtual이어야 한다.

03

값 전달을 막는다

다형 객체는 참조나 포인터로 다루고, 값 복사는 clone 같은 명시 함수로 분리한다.

public 상속
인터페이스 확장 파생 클래스는 기반 클래스의 계약을 더 좁게 만들면 안 된다.
precondition 강화는 위험하다.
protected 상속
구현 공유 외부 대체 가능성은 주지 않고 내부 구현만 빌린다.
합성이 더 단순한지 비교한다.
virtual 소멸자
다형 수명 기반 포인터로 파생 객체를 지울 때 파생 소멸자가 호출된다.
인터페이스 기반 클래스의 기본값이다.
slicing
파생 정보 손실 Derived를 Base 값으로 복사하면 Derived 멤버와 가상 행동 문맥을 잃는다.
Base& 또는 unique_ptr<Base>를 쓴다.

is-a · 삭제 경로 · 재사용 욕심 점검

is-a 호출자가 기반 타입에 기대한 모든 행동을 파생 타입이 깨지 않는가.
삭제 경로 base pointer 소유권이 있다면 기반 소멸자가 virtual인지 확인한다.
재사용 욕심 단순히 코드 몇 줄을 공유하려고 상속을 쓰는 것은 아닌가.

다형 기반 타입

class Shape {
public:
    virtual ~Shape() = default;
    virtual double area() const = 0;
        overflow-wrap: break-word;
        word-break: keep-all;
      };