- 다형성, 추상클래스, 인터페이스를 실습할 수 있는 과제
- 가상함수, 순수가상함수를 실습
- orthodox canonical form은 항상 준수
- 생성자, 소멸자 호출시 적절한 메시지를 출력해주어야 함
Animal 클래스
- 자식들이 재정의해서 사용할 makeSound()는 가상함수로 선언
- 소멸자도 가상함수로 만들어 적절하게 호출되도록 해야함
- Protected인 함수, 변수는 외부에서는 접근이 불가능하고 자기자신과 자신을 상속받은 자식들만 접근할 수 있음
Protected
- std::string type;
Public
- void makeSound();
각 동물에게 적절한 울음소리를 출력- std::string getType();
type을 반환해줌class Animal { protected: std::string type; public: Animal(); Animal(const Animal &animal); Animal &operator=(const Animal &animal); virtual void makeSound() const; std::string getType() const; virtual ~Animal(); };
Cat 클래스
- Animal클래스를 상속받음
- makeSound함수를 적절하게 오버로딩
- type은 "Cat"으로 초기화되어야 함
Public
- void makeSound();
class Cat : public Animal { public: Cat(); Cat(const Cat &cat); Cat &operator=(const Cat &cat); void makeSound() const; ~Cat(); };
Dog 클래스
- Animal클래스를 상속받음
- makeSound함수를 적절하게 오버로딩
- type은 "Dog"으로 초기화되어야 함
Public
- void makeSound();
class Dog : public Animal { public: Dog(); Dog(const Dog &Dog); Dog &operator=(const Dog &Dog); void makeSound() const; ~Dog(); };
WrongAnimal 클래스
- Animal과 동일하지만 한가지 다르게 makeSound(), Destructor를 가상함수로 만들지않음
class WrongAnimal { protected: std::string type; public: WrongAnimal(); WrongAnimal(const WrongAnimal &wronganimal); WrongAnimal &operator=(const WrongAnimal &wronganimal); void makeSound() const; std::string getType() const; ~WrongAnimal(); };
WrongCat 클래스
- WrongAnimal클래스를 상속받음
- Cat과 동일
- WrongAnimal의 makeSound()가 가상함수가 아니기때문에 호출시 WrongCat것이 아닌 WrongAnimal의 makeSound()가 호출됨
- Destructor역시 WrongAnimal에서 virtual로 만들지않았기 때문에 부모의 소멸자가 호출되게됨
class WrongCat : public WrongAnimal { public: WrongCat(); WrongCat(const WrongCat &wrongcat); WrongCat &operator=(const WrongCat &wrongcat); void makeSound() const; std::string getType() const; ~WrongCat(); };
- Brain클래스를 추가하고 Cat과 Dog에 Private Brain* 변수를 추가해줌
- Cat과 Dog의 생성자에서는 new Brain()을 해주어야 함
- 소멸자에서는 delete Brain을 해주어야 함
- Cat과 Dog에서 일어나는 복사는 얕은복사가아닌 깊은복사가 이뤄져야함
Brain 클래스
class Brain { private: std::string ideas[100]; public: Brain(); Brain(const Brain &brain); Brain &operator=(const Brain &brain); ~Brain(); void setIdeas(std::string str, int i); void setAllIdeas(std::string str); std::string getIdeas(int i) const; };
Cat 클래스
- 생성자에서는 new Brain()을 통해 Brain의 저장공간을 할당해줘야하고 소멸자에서는 회수해주어야 함
class Cat : public Animal { private: Brain *brain; public: Cat(); Cat(const Cat &cat); Cat &operator=(const Cat &cat); void makeSound() const; ~Cat(); Brain *getBrain() const; };
Dog 클래스
- 생성자에서는 new Brain()을 통해 Brain의 저장공간을 할당해줘야하고 소멸자에서는 회수해주어야 함
class Dog : public Animal { private: Brain *brain; public: Dog(); Dog(const Dog &dog); Dog &operator=(const Dog &dog); void makeSound() const; ~Dog(); Brain *getBrain() const; };
- Animal클래스를 추상클래스로 만들어야 함
Animal 클래스
- getType() 함수를 순수가상함수로 만들어주어 Animal클래스를 추상클래스로 만들었음
- virtual 키워드를 사용한 가상함수는 자식이 재정의하여 사용할 수 있고 재정의 하지않으면 부모의 함수를 그대로 사용
- virtual과 = 0 을 사용해 만든 순수가상함수는 자식이 무조건 재정의 하여야 사용이 가능함
- 추상클래스는 단독으로 객체화할 수 없음
- 추상클래스는 자식클래스에게 클래스의 틀을 제공하는 청사진이되어 Interface로서 동작하게됨
class Animal { protected: std::string type; public: Animal(); Animal(const Animal &animal); Animal &operator=(const Animal &animal); virtual void makeSound() const; virtual std::string getType() const = 0; virtual ~Animal(); };