[42Seoul] CPP04 virtual
Exercise 00
Animal 이라는 기본 클래스를 구현, 보호되는 특성은 각 type입니다.
Animal로 상속한 Dog, Cat 클래스를 구현합니다.
두 파생 클래스는 이름에 따라 유형 필드를 설정, Dog 유형은 Dog로 Cat 유형은 Cat으로 초기화해야 합니다.
Animal 클래스의 유형은 비워두거나 선택한 값으로 설정할 수 있어야 합니다.
울부짖어야 합니다
WrongAnimal 클래스를 상속하는 WrongCat 클래스를 구현합니다.
WrongCat makeSound 함수 실행시, WrongAnimal이 울부짖어야 합니다.
무엇이 모른 채 왜 안될까만 하다가 Virtual 이라는 키워드를 던져준 @sanjeon 감사합니다.
가상 함수
virtual 멤버함수의원형;
부모 클래스에서 상속받을 클래스에서 재정의할 것이라고 기대하고 정의해놓은 함수
왜 이걸 써야 하는데?
가상 함수를 사용하지 않은 부모 클래스형 포인터로 멤버 함수를 호출할 때, 컴파일러는 정적타입⚀을 보고 타입에 맞는 멤버 함수를 호출합니다. 정적으로 바인딩 되어있는 함수를 가상함수를 통해서 동적으로 바인딩 할 수 있습니다. 즉, 가상함수로 선언하면 포인터의 타입이 아닌 포인터가 가르키는 객체의 타입에 따라 멤버 함수를 선택하게 됩니다.
⚀정적타입 : 컴파일할 때, 함수를 호출하는 코드를 고정된 메모리 주소로 변환합니다 (정적 바인딩)
가상 함수 테이블
가상함수 포인터 배열이라고 생각하면 됩니다.
가상 소멸자
기초 클래스의 소멸자는 반드시 가상으로 선언해야 합니다.
Person* park = new Student;
...
delete park;
Person 클래스는 Student 클래스의 기초 클래스로 park이라는 Student 객체가 동적으로 할당
delete 키워드는 ~Student() 소멸자를 호출하지 않고 ~Person()소멸자를 호출하면서, 동적으로 할당된 메모리는 정상적으로 해제되지 않습니다. 따라서 명시적으로 소멸자를 선언할 필요가 없더라도, 아무 일도 하지 않는 가상 소멸자를 선언해야 합니다.
Exercise01
각 클래스마다 생성자와 소멸자에 대한 특별한 메세지가 필요합니다.
array of 100 std::string 으로 된 ideas를 포함한 Brain 클래스를 만들어야 합니다.
Dog and Cat은 private Brain* 을 가져야 합니다.
- 생성 시, new Brain()을 사용해야 합니다.
- 소멸 시, delete Brain을 사용해야 합니다.
main 문에서 배열로 된 Animal을 생성합니다.
그 중에 절반은 Dog, 다른 절반은 Cat으로 되어야 하며, 배열을 반복을 통해 모든 Animal을 삭제(dogs and cats Animal로써 삭제)합니다. 메모리 릭 체크를 합니다.
얕은 복사는 안되며, 복사본이 깊은 복사인지 테스트를 해야합니다.
Exercise 02
기본 Animal 클래스는 인스턴스화할 수 없습니다.
아무도 인스턴스화할 수 없도록 동물 클래스를 수정합니다. 모든 것이 예전처럼 작동해야 한다.
과제에서 요구하는 것은 추상클래스를 사용하라는 의미입니다.
하나 이상의 순수 가상 멤버 함수를 선언하여야 합니다.
구체적인 클래스가 파생될 수 있는 일반 개념의 식 역할, 추상 클래스는 개체로 만들 수 없습니다.
순수 가상 함수가 하나도 없는 클래스를 추상 클래스로 만들고 싶을때에는 소멸자를 순수 가상 함수로 만든다.
순수 가상 함수
가상 함수는 파생 클래스에서 재정의할 것으로 기대하는 멤버 함수로 재정의가 가능한 함수를 의미하는 반면에
순수 가상 함수는 파생 클래스에서 반드시 재정의해야 하는 멤버 함수를 의미
선언만 있고 구현이 없는 가상 함수로 함수 선언부 끝에 "=0"을 추가하면 됩니다.
virtual 맴버함수의 원형 = 0;
추상 클래스
다형성을 가진 함수의 집합을 정의 할 수 있게 합니다.
동작이 정의되지 않은 순수 가상 함수를 포함하고 있어야하며, 인스턴스를 생성할 수 없습니다.
상속을 통해 파생 클래스를 만들고, 만든 파생 클래스에서 순수 가상 함수를 모두 오버라이딩하고 나서야 파생 클래스의 인스턴스를 생성할 수 있게 됩니다. 추상 클래스 타입의 포인터와 참조를 바로 사용할 수 있습니다.
추상 클래스의 용도 제한
- 변수 또는 멤버 변수
- 함수의 전달되는 인수 타입
- 함수의 반환 타입
- 명시적 타입 변환의 타입