다형성에 대해서 알아 봅시다.
아래와 같은 코드가 있습니다.
부모 클래스로 만든 객체와
자식 클래스로 만든 객체가 있습니다.
부모 클래스로 만든 포인터에
부모 클래스로 만든 객체의 주솟값을 저장합니다.
자식 클래스로 만든 포인터에
자식 클래스로 만든 객체의 주솟값도 저장을 합니다.
이는 문제가 되지 않죠? 기본적인 포인터 문법입니다.
그럼 아래와 같은 경우는 어떨까요?
부모 클래스로 만든 포인터에
자식 클래스로 만든 객체의 주솟값을 저장하는 건
문제가 없습니다.
근데 자식 클래스로 만든 포인터에
부모 클래스로 만든 객체의 주솟값을 저장하는 건
문제가 발생합니다.
왜 그럴까요?
아래 그림을 보시죠.
위에는 부모 클래스형 포인터로 자식 클래스형 객체를
가리킬 때이며 아래는 자식 클래스형 포인터로
부모 클래스형 객체를 가리킬 때 메모리 상황입니다.
자식 클래스형 객체는 메모리상에
부모 - 자식 클래스순으로 할당이 된다고 하였죠?
포인터의 자료형이 의미하는 것은
가리키는 데이터를 해당 자료형으로 보겠다는 것이죠.
즉 위 그림은 부모 - 자식 클래스순으로 할당된 데이터를
부모 클래스형 데이터로 보는 상황입니다.
어차피 가리키는 공간에 부모 클래스형 데이터가
존재하므로 문제가 되지 않죠.
반대로 아래 그림은 자식 클래스형 포인터가 가리키는
공간에 부모 클래스형 데이터가 존재하죠.
부모 클래스형 데이터를 자식 클래스형 데이터로
인식하려고 하니 오류가 발생하는 겁니다.
자식 클래스형 포인터는 부모 클래스형
객체를 가리킬 수 없지만, 잘 생각해 보면
부모 클래스형 포인터는 부모 클래스를 상속받은
자식 클래스로 만든 객체라면, 어떤 객체든지
가리킬 수 있는 겁니다.
자식 클래스형 객체의 맨 앞에는 결국
부모 클래스형 데이터가 존재할테니까요.
근데 이것만으로 다형성을
설명하기에는 부족합니다.
main 함수에서
자식 클래스형 객체를 가리키는 부모 클래스형
포인터를 통해 함수를 호출하였습니다.
부모 클래스형 포인터로 접근을 했지만
실제 가리키는 객체는 자식 클래스형이므로
자식 클래스에 오버라이딩 되어 있는
Output 함수가 호출되기를 바랍니다.
그런데 의도와는 다르게 부모 클래스에
있는 Output 함수가 호출되었죠.
이것을 통해 알 수 있는 것은
부모 클래스형 포인터는 자식 클래스로 만든
어떤 객체든지 가리킬 수 있지만,
바꾸어 말하면 가리키고 있는 객체가
어떤 객체이든지 부모 클래스형
객체로 보고 있다는 것이죠.
이러면 다형성이 아니라 통일성이라고 봐야죠.
이러한 문제를 해결하기 위해
C++에서는 가상 함수를 제공합니다
부모 클래스에서 오버라이딩된 멤버 함수 앞에
'virtual' 키워드를 붙여 주면 되죠.
부모 클래스로 가서
오버라이딩을 진행한 Output이라는
멤버 함수 앞에 virtual 키워드를 붙이고
다시 실행해 보았습니다.
의도한 대로 자식 클래스형 객체를 가리키는
부모 클래스형 포인터를 통해 Output 함수를
호출하였더니, 자식 클래스 쪽
Output 함수가 호출된 것을 확인할 수 있습니다.
강의 출처 : https://www.youtube.com/watch?v=SupqA0ujuog&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&index=84
'C++ > 기초' 카테고리의 다른 글
C++ 기초 : 다형성 (2) (0) | 2024.05.04 |
---|---|
C++ 기초 : 상속 (2) (0) | 2024.05.04 |
C++ 기초 : 오버라이딩 (0) | 2024.05.03 |
C++ 기초 : 상속 (1) (0) | 2024.05.03 |
C++ 기초 : tree (10) (0) | 2024.05.03 |