위 클래스의 생성자를 따라가보자. 생성자에서 가장 먼저 처리하는 것이 부모 클래스의 생성자를 호출하는 것이다. 다중상속에서의 생성자 호출순서는 상속할 때 앞에 기재했던 순서대로 호출된다. 추적하기 쉽도록 생성자에 클래스의 이름을 출력하도록했다.
void PlusA()
{
std::cout << ++MiddleA::Top::top_a << std::endl;
std::cout << ++MiddleB::Top::top_a << std::endl;
}
결국 Top이 2번 생성되었다. Top이 1번 생성되고 MiddleA와 MiddleB가 같은 Top을 가리킨다면 Bottom의 멤버 함수인 위 코드를 실행했을 때 2가 출력되어야하지만, 실제로는 1만 출력되었다.
가장 좋은 해결방법이라고 생각한다. 문제가 발생할 여지가 적고, C#, JAVA등 많은 언어들은 다중 상속을 지원하지 않아 다이아몬드 상속이 일어나지 않음에도 불구하고, 완성된 프로그램을 개발할 수 있다.
위의 예제 코드와 같이 부모중 하나를 경유해서 접근한다. 모호성만 해결할 수 있어, 메모리 낭비가 존재한다.
부모 클래스에서 virtual 키워드로 조상 클래스를 상속받는다. 이러면 조상 클래스는 가상 기저 클래스가 되며 생성자는 1회만 호출된다. 하지만 부모 클래스 각각에 가상 기저 클래스의 멤버에 대한 오프셋이 들어있는 테이블의 포인터가 생성된다. 간단한 클래스의 경우 메모리가 증가할 수 있다.
일반적으로 이 테이블의 포인터는 가상 함수 테이블의 포인터 바로 뒤에 위치한다. 따라서 가상 기저 테이블에는 자신의 객체에 대한 오프셋 또한 들어있다.