이번 편의 목표: 부모 타입의 참조로 자식의 연체료 계산을 호출하고, 소멸자를 가상 함수로 둡니다.
상속은 부모의 공개 약속을 자식이 물려받는 관계입니다. virtual 함수는 호출 때 참조나 포인터가 실제로 가리키는 객체의 함수를 실행합니다. override는 부모의 가상 함수를 재정의한다는 검사입니다. 서명이 다르면 컴파일 오류가 납니다.
#include <iostream>
class FeePolicy {
public:
virtual ~FeePolicy() = default;
virtual int fee(int days) const = 0;
};
class PaperFee : public FeePolicy {
public:
int fee(int days) const override {
return days * 100;
}
};
class VideoFee : public FeePolicy {
public:
int fee(int days) const override {
return days * 300;
}
};
void print_fee(const FeePolicy &policy, int days) {
std::cout << policy.fee(days) << '\n';
}
int main() {
PaperFee paper;
VideoFee video;
print_fee(paper, 3);
print_fee(video, 3);
return 0;
}출력은 300과 900입니다. print_fee는 자식 타입을 모릅니다. fee가 virtual이므로 실제 객체의 함수가 실행됩니다. = 0이 붙은 함수는 순수 가상 함수이고, FeePolicy 자신은 객체를 만들 수 없습니다.
부모 포인터로 자식을 delete하려면 부모 소멸자가 virtual이어야 합니다. 그렇지 않으면 그 삭제의 의미가 정의되지 않습니다. 이번 예제는 참조로만 전달해 그 삭제를 만들지 않습니다. 값으로 FeePolicy policy = paper처럼 받으면 자식 부분이 잘려 부모만 남습니다. 다형성을 유지할 때는 값 복사가 아니라 참조나 포인터를 사용합니다.
직접 해 보기
VideoFee의 하루 요금을 500으로 바꾸고 2일의 결과가 1000인지 확인하세요.
해설
2 곱하기 500은 1000입니다. print_fee의 매개변수 타입은 계속 FeePolicy 참조입니다. 호출부에 VideoFee 객체를 넘기면 재정의한 fee가 실행됩니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.