Exercise 00 : Polymorphism

Polymorphism(다형성) : 객체의 런타임 형(type)에 따라 함수 기능에 차이를 보이는 성질
C++에서는 어떠한 클래스의 포인터 변수에 해당 클래스의 하위 클래스 객체의 주소도 할당할 수 있도록 허용됨
따라서 Animal 클래스의 포인터 변수를 선언시 하위 클래스인 DogCat을 사용할 수 있음
이 경우 virtual 키워드로 정의된 멤버 함수는 하위 클래스에서 재정의된 것으로 동작하고, 나머지는 현재 선언된 클래스의 것을 따름


const로 선언된 클래스 객체의 경우 const로 선언된 멤버 함수만 사용 가능


Exercise 01 : I don’t want to set the world on fire

새롭게 할당받는 포인터 멤버 변수가 존재할 시, 복사와 소멸에 주의를 기울일 필요가 있음

복사시

  • 단순히 포인터 변수를 그대로 복사한다면 원본과 복사본의 포인터 변수가 가리키는 대상이 같아지므로 일반적으로 정의하는 복사라고 볼 수 없음
  • 따라서 포인터가 가리키는 대상까지 복사하는 깊은 복사(deep copy)가 수행되어야함

소멸시

  • 포인터 변수에 할당된 메모리는 소멸시 자동으로 해제되지 않음
  • 따라서 소멸자에서 따로 메모리를 해제하는 과정을 구현해야함

Exercise 02 : Abstract class

추상 클래스(Abstract class)는 그 이름처럼 추상적으로만 존재하는 클래스를 뜻함

  • 즉, 해당 클래스의 객체는 직접 생성될 수 없음
  • virtual로 선언되고, 해당 클래스에서 정의되지 않는 순수 가상함수(pure virtual function)이 존재할 경우 해당 클래스는 자동적으로 추상 클래스가 됨
  • 추상 클래스에서 정의된 함수는 상속시에 그대로 사용할 수 있으나, 순수 가상함수의 경우에는 파생 클래스에서 반드시 따로 정의가 되어있어야 함

Exercise 03 : Interface & recap

각 클래스들의 계층을 파악하는 것이 중요

  • Character 클래스는 추상 클래스인 ICharacter를 상속받으며, Amateria 클래스 객체의 배열을 멤버변수로 소유
    • equip 멤버 함수로 Amateria 객체를 저장
    • unequip 멤버 함수로 저장해놓은 Amateria 객체를 제거
    • use 멤버 함수로 Amateria 클래스의 use 멤버 함수를 호출
  • MateriaSource 클래스도 추상 클래스인 IMateriaSource를 상속받으며, Amateria 클래스 객체의 배열을 멤버변수로 소유
    • learnMateria 멤버 함수로 Amateria 객체를 저장
    • createMateria 멤버 함수로 저장해놓은 Amateria 객체를 clone()하여 반환
  • Amateria 클래스를 부모 클래스로 하는 Ice, Cure 클래스가 존재
    • clone 멤버 함수는 virtual로 선언되어 각 하위 클래스에서 자기 자신을 복사한 객체를 생성하여 반환
    • use 멤버 함수도 virtual로 선언되어 각 하위 클래스마다 다른 동작을 실행


다시 정리해보면,

  • 각각의 AMateria들(Ice, Cure)은 먼저 MateriaSource 클래스에 학습되어야함
  • Character 클래스는 MateriaSource에 학습되어있는 AMateria를 생성하여 장착할 수 있으며, 장착 해제할 수도 있음
  • Character 클래스는 장착한 AMateria를 사용할 수 있음

각각의 AMateria들은 포인터 변수로 저장되어있으므로 복사 및 소멸시 주의해야함
메모리 해제 이후 해당 포인터 변수에 nullptr을 할당하는 Defensive-Style을 활용하는 것이 좋음