추상 클래스

추상 클래스 계약

순수 가상 함수로 다형 계약을 만들 때는 override뿐 아니라 base pointer 삭제, virtual destructor, default 구현, 객체 slicing까지 같이 봐야 안전하다.

01

계약 선언

기반 클래스에 draw(), area() 같은 필수 동작을 순수 가상 함수로 둔다.

interface
02

자식 구현

파생 클래스가 override로 정확한 시그니처를 구현한다.

컴파일 점검
03

기반 포인터 사용

Shape*나 unique_ptr<Shape>로 실제 타입을 숨기고 가상 호출을 수행한다.

dynamic dispatch
04

소멸 처리

base 포인터로 삭제될 수 있으면 virtual destructor가 필요하다.

cleanup
no virtual dtor
파생 소멸자가 호출되지 않음 base 포인터 delete 시 자원 누수가 날 수 있다.
UB risk
missing override
시그니처가 달라도 새 함수가 됨 override 키워드를 붙이면 잘못된 오버라이드를 컴파일러가 잡는다.
signature
slicing
값 복사로 파생 부분 손실 다형 객체는 값이 아니라 참조/포인터로 다룬다.
object slicing
fat interface
자식이 필요 없는 함수까지 구현 인터페이스 분리 원칙에 맞게 작은 추상 클래스로 나눈다.
ISP

설계 질문

소유권 다형 객체를 누가 소유하는지 unique_ptr/shared_ptr로 명확히 한다.
기본 구현 공통 코드가 필요하면 순수 인터페이스 대신 일부 virtual 기본 구현을 둔다.
성능 가상 호출 비용이 문제인 핫 경로라면 템플릿 다형성도 고려한다.