구현 흐름

`Dog` 객체는 `Animal` 부분을 먼저 만들고 파생 멤버를 덧붙인다

상속 구현은 선언, 기반 생성자 호출, 파생 멤버 초기화, 재정의 함수 호출, 소멸 순서까지 하나의 흐름으로 읽으면 명확하다.

상속 선언 1
`class Dog : public Animal`로 기반 인터페이스를 파생 객체에 공개한다.
기반 초기화 2
`Animal(n, "개", a)`가 먼저 실행되어 이름, 종, 나이를 채운다.
파생 초기화 3
`breed(b)`로 `Dog` 전용 상태를 채우고 생성자 본문을 실행한다.
함수 호출 4
`displayInfo()`는 `Dog` 구현에서 기반 출력 뒤 견종을 추가한다.
소멸 5
객체가 끝나면 `Dog` 소멸자 다음 `Animal` 소멸자가 호출된다.
생성자 초기화 리스트 base first
Dog(string n, int a, string b)
  : Animal(n, "개", a), breed(b) {
  cout << getName();
}
void displayInfo() const override {
  Animal::displayInfo();
  cout << "견종: " << breed;
}
`Dog myDog`의 내부 구성 파생 객체는 기반 클래스 부분 객체와 파생 클래스 전용 멤버를 함께 가진다.
Animal 부분 name = 바둑이 species = 개 age = 3 displayInfo(), getName()
Dog 부분 breed = 진돗개 bark() displayInfo() override ~Dog() 이후 ~Animal()
`myDog.displayInfo()` `Dog::displayInfo()`가 선택되고, 그 안에서 `Animal::displayInfo()`를 명시 호출한다.
`myDog.bark()` `Dog`가 새로 추가한 멤버 함수라서 기반 클래스에는 없는 동작이다.
`myDog.getName()` public 상속 덕분에 기반 클래스의 public getter를 파생 객체에서 그대로 쓴다.
흐름 핵심 생성은 기반에서 파생으로, 소멸은 파생에서 기반으로 진행된다. 함수 재정의는 기존 인터페이스를 유지한 채 파생 클래스에 맞는 결과를 더하는 방식이다.