상속 관계에서 Dynamic Polymorphism을 만드는 virtual function, virtual table 에 대해 알아보자.
예제1)
double 사이즈는 8byte이므로,
상속받은 cat의 사이즈는 16byte. (double 변수 2개)
Dynamic Polymorphism을 구현하기 위해서
speak 함수에 virtual을 넣어주고
derived 클래스에 override를 넣어주게 되면
사이즈가 바뀐다!
그 이유는, address 주소 정보가 추가로 들어가기 때문이다.
Base 클래스인 Animal 의 경우, double 타입의 height 정보를 가지고 있어서 8 byte,
Cat 의 경우 Base 클래스의 height 정보와 Cat 클래스만의 double 타입 weight 정보까지 있어 16 byte,
그리고 여기에 새로운 정보가 추가된다.
바로 포인터 정보가 추가된 것이다.
64bit 환경에서 모든 포인터는 8 byte의 크기를 가지므로 16, 24 bytes 가 된 것이다.
이 포인터들은 각각의 virtual table 을 가리키고 있다.
virtual table, VT 안에는 포인터 정보가 있다.
Animal VT 안의 포인터는 Animal::speak()를 가리키는 정보(주소)가 들어 있을 것이고,
Cat VT 안의 포인터에는 Cat::speak() 함수를 가리키는 주소가 들어 있는 것이다.
결국 Animal 과 Cat 의 포인터 정보는 각각에 맞는 VT를 가리키게 되는 것.
메인함수 코드를 바꿔보면
1) Animal * 는 스택 위에 포인터 정보를 갖고 있는 polyAnimal 이라는 8 byte의 주소 정보가 들어온 것이고,
2) new 키워드를 통해 힙 위에 고양이 object를 만들어 냈다. (24byte의 크기)
3) 스택에서 Animal* 는 힙 위의 고양이 object를 가리키는 것이다.
4) 고양이 object 에서 VT의 주소를 가리키는 *는 Cat VT를 가리키게 된다.
5) polyAnimal에서 speak 함수를 호출해 주었다.
이 때 speak 함수를 호출해 주기 위해서 pointer가 가리키는 VT로 따라가서 Cat VT가 가리키고 있는 speak() 함수의 출력 부분을 실행해주게 된다.
6) 마지막으로 힙 위에 올라가 있는 polyAnimal object를 해제시켜 주는 것이다.
만약 new Cat 대신 new Animal 을 넣어주게 되면 Animal VT를 가리키는 식으로 바뀌는 것.
*바로 이전 게시글에서 base 클래스의 destructor는 virtual로 만들어야 한다고 언급한 적 있다.
이제 설명이 가능한데,
맨 위 코드에서 virtual ~Animal()=default;를 살려주게 되면
디스트럭터도 하나의 함수이기 때문에
Animal VT 안에 ~Animal() 을 가리키는 포인터 정보가 들어온 것이다.
Cat VT 안에도 마찬가지로 ~Cat()을 가리키는 포인터 정보가 들어온다.
코드 섹션 어딘가에는 고양이의 디스트럭터 정보와 동물의 디스트럭터 정보가 쓰여져 있을 것이고,
Virutal Table에서는 이 코드를 가리키게 되는 것이다.
-가끔 virtual과 override 등을 안 붙이거나 아무 생각 없이 사용하는 사람들이 있는데,
Dynamic Polymorphism은 마법처럼 자동으로 구현되는 것이 아니라 이런 정확한 원리로 구현되는 것이다.
'모던C++ > 상속관계 Inheritance' 카테고리의 다른 글
8. Dynamic Cast _C++ (0) | 2022.09.02 |
---|---|
7. Virtual Inheritance 가상 상속_C++ (0) | 2022.09.01 |
6. 다중 상속 multiple inheritance _ C++ (0) | 2022.09.01 |
5. Pure Virtual Function 순수 가상 함수_ C++ (0) | 2022.09.01 |
3. 가상 함수 Virtual Function _ C++ / Dynamic Polymorphism (0) | 2022.08.23 |
2. 접근 권한 키워드 - public, private, protected, 파생 클래스 _ C++ (0) | 2022.08.23 |
1. Inheritance 상속이란? _ C++ (0) | 2022.08.23 |