- cpp03은 클래스의 상속과 관련한 실습을 할 수 있는 과제이다
- 여러가지 상황에서의 상속을 실습
- -Wshadow, -Wno-shadow 플래그 사용해보기
ClapTrap 클래스
- 모든 생성자와 소멸자는 호출시 메시지를 출력해야함.
- 모든 멤버변수는 실행시 적절한 메시지를 출력해야함.
Private
- Name (생성자 매개변수로 사용)
- Hit Points (10)
- Energy points (10)
- Attack damage (0)
Public
- void attack(const std::string& target);
target에 attack시 target은 Attack damage만큼의 Hit points 감소하며 1 Energy Points 감소, 단 Energy points가 0이라면 불가.
- void takeDamage(unsigned int amount);
attack 당할시 amount만큼의 Hit points 감소
- void beRepaired(unsigned int amount);
amount만큼의 Hit Points를 회복하며 1 Energy Points 감소, 단 Energy points가 0이라면 불가
class ClapTrap { private: std::string name; int Hit_points; int Energy_points; int Attack_damage; public: ClapTrap(); ClapTrap(std::string name); ClapTrap(const ClapTrap &claptrap); ClapTrap &operator=(const ClapTrap &claptrap); void attack(const std::string& target); void takeDamage(unsigned int amount); void beRepaired(unsigned int amount); ~ClapTrap(); };
ScavTrap 클래스
- ClapTrap클래스로부터 상속
- 생성자 호출순은 ClapTrap -> ScavTrap
- 소멸자는 생성자의 역순
- 생성자, 소멸자, attack은 ClapTrap과 다른 메시지를 출력해야함
Private
- Name (생성자 매개변수로 사용)
- Hit Points (10)
- Energy points (10)
- Attack damage (0)
Public
- void guardGate();
class ScavTrap : public ClapTrap { public: ScavTrap(); ScavTrap(std::string name); ScavTrap(const ScavTrap &scavtrap); ScavTrap &operator=(const ScavTrap &scavrtrap); void attack(std::string const &target); void guardGate(); ~ScavTrap(); };
FragTrap 클래스
- ClapTrap클래스로부터 상속
- 생성자 호출순은 ClapTrap -> FragTrap
- 소멸자는 생성자의 역순
- 생성자, 소멸자는 ClapTrap과 다른 메시지를 출력해야함
Private
- Name (생성자 매개변수로 사용)
- Hit Points (100)
- Energy points (100)
- Attack damage (30)
Public
- void highFivesGuys(void);
class FragTrap : public ClapTrap { public: FragTrap(); FragTrap(std::string name); FragTrap(const FragTrap &fragtrap); FragTrap &operator=(const FragTrap &fragtrap); void highFivesGuys(void); ~FragTrap(); };
DiamondTrap 클래스
- ScavTrap, FragTrap 클래스로부터 상속
- 생성자 호출순은 ClapTrap -> FragTrap and ScavTrap -> DiamondTrap
- 소멸자는 생성자의 역순
- 다중상속시 부모의 생성자가 두번호출되고, 멤버변수 및 멤버함수가 중복되어 모호해지는 문제를 해결하기위해 가상상속(virtual inheritance)을 사용
Private
- Name (생성자 매개변수로 사용)
- Hit Points (FragTrap)
- Energy points (ScavTrap)
- Attack damage (FragTrap)
Public
- attack() (ScavTrap)
- void whoAmI();
class DiamondTrap : public FragTrap, public ScavTrap { private: std::string name; public: DiamondTrap(); DiamondTrap(std::string name); DiamondTrap(const DiamondTrap &diatrap); DiamondTrap &operator=(const DiamondTrap &diatrap); void whoAmI(); void attack(const std::string &target); ~DiamondTrap(); };
- A -> B,C -> D 의 구조로 상속시 다이아몬드 상속이 됨
- D객체 생성시 A의 생성자가 두번 호출되게되고 소멸자 역시 두번 호출됨.
- 이것은 A의 멤버변수, 멤버함수또한 두개씩 만들어져 호출시 어떤 부모의 변수, 함수를 호출한것인지가 모호해지는 문제가 발생함
- 해결을 위해 가상상속을 사용하여 virtual base 포인터를 통해 한번만 생성된 부모의 변수, 함수에 접근할 수 있도록 할 수 있음
- 이때 포인터의 생성으로 기존의 데이터보다 크기가 커질수도 있고 이는 성능저하를 야기할 수 있음