Polymorphic Use

다형성은 값 복사보다 참조와 포인터로 유지한다

virtual 함수가 있어도 객체를 기반 클래스 값으로 복사하면 파생 클래스 부분이 사라집니다. 호출 방식과 소유권을 같이 정해야 동적 바인딩이 살아 있습니다.

값 복사 파생 부분이 잘려 나갈 수 있음
참조 소유권 없이 실제 객체를 가리킴
포인터 다형성과 선택적 소유를 표현
slicing

기반 타입 값으로 받는 경우

void drawOne(Shape s) { s.draw(); }

Circle을 넘겨도 Shape 부분만 복사되어 Circle의 상태와 재정의 의미가 사라질 수 있습니다.

dispatch

참조나 포인터로 받는 경우

void drawOne(const Shape& s) { s.draw(); }

실제 객체의 타입이 유지되어 vtable을 통해 Circle, Rectangle의 구현이 호출됩니다.

const Shape&

읽기 전용으로 사용하고 소유권이 필요 없을 때 가장 가볍습니다.

Shape*

null 가능성이나 수명 관리 책임을 명확히 표시해야 합니다.

unique_ptr<Shape>

다형 객체의 소유권을 컨테이너나 함수로 이동할 때 사용합니다.

점검표

기반 클래스 API에는 안전 장치가 필요합니다

다형 객체를 다룰 때는 override 검증, virtual 소멸자, 복사 금지 정책을 함께 확인하면 나중에 생기는 미묘한 런타임 문제를 줄일 수 있습니다.

virtual dtor 기반 포인터로 삭제할 수 있다면 소멸자는 virtual
override 함수 시그니처 실수를 컴파일 단계에서 확인
copy policy 값 복사를 막거나 clone 같은 명시적 복제를 제공