부모 클래스를 상속받은 자식 클래스에서 부모의 멤버 함수와 동명의 함수를 함수 오버라이딩 없이 사용할 경우, 부모의 함수가 호출되는 경우가 있다. Parent타입의 변수에 다른 객체(Child 타입의 객체)를 넣더라도 마찬가지임. 컴파일러가 Parent의 해당 함수를 바인딩 한 채로 빌드를 끝내버리기 때문.
이를 해결하기 위해 일단 virtual
키워드를 호출했을 때 생성되는 가상 함수 테이블에 대해 알아보자.
컴파일 시 가상함수가 정의된 클래스가 있다면, 가상 함수 테이블이 만들어져 바이너리 rdata 영역에 기록되며, 해당 클래스로 만들어진 객체에서 함수를 호출할때 해당 클래스의 가상 함수 테이블을 참조해 함수를 호출한다.
C++에서는 다중상속을 지원한다. 장단점이 분명한데, 다이아몬드 구조를 떠올리면 이해하기 쉽다.
유연한 상속을 보장해주는 대신, 메모리 낭비, 성능 저하로 이어질 수 있다. 왜?
B도 A를 상속하고, C도 A를 상속하니 virtual
키워드 없이 컴파일 했다면 아마 A의 생성자와 소멸자가 각각 한번씩 총 두번 호출됐을 것이다. A의 멤버에 접근하려면 B::A_member, C::A_member 이런식으로 해야한다.
이때 사용할 수 있는 것이 virtual
키워드 이다.
B와 C가 virtual 키워드로 A를 상속받으면 문제 해결. 그러나 메모리의 크기는 증가한다. 왜?
virtual base pointer가 메모리에 저장되기 때문.