다음 코드와 같은 다중 상속 관계가 있다고 가정합시다.
class A { ... };
class B: virtual public A { ... };
class C: virtual public A { ... };
class D: public B, public C { ... };
이 때 D 클래스 객체가 메모리에 올라간 구조는 대략 다음과 같을 것입니다(순서는 중요하지 않습니다. 포인터가 추가되었음이 중요합니다).
실제로 저렇게 메모리에 올라갈지는 모릅니다. 컴파일러 구현에 따라 다르거든요.
심지어 어떤 컴파일러는 포인터를 추가하지 않는 경우도 있습니다(이런 경우에는 vptr과 vtbl이 맡은 부담이 2배로 늘어납니다).
여기에 가상 테이블 포인터까지 표현하면 다음과 같이 될 것입니다(역시 순서는 중요하지 않습니다).
컴파일러가 추가해 준 부분은 회색으로 칠했습니다. 들어간 포인터들과 데이터 멤버들이 차지하는 비율은 데이터 멤버가 얼마나 많으냐에 따라 달라질 수 있으므로, 이 그림을 너무 맹신하면 안됩니다.
특이한 점은, 네 개의 클래스가 들어갔는데 vptr은 세 개뿐입니다.
이것은 컴파일러가 B와 D가 vptr을 공유할 수 있음을 이용하여 최적화를 한 결과입니다.
상세 내용 접기