죽음의 다이아몬드란?

죽음의 다이아몬드는 다중 상속을 지원하는 프로그래밍 언어, 특히 여러 클래스 서로 상속할 때 일어나는 상속 계층간의 구조에서 발생 문제를 설명하는데 쓰이는 용어이다.

C++에서 가장 일반적으로 연관되어있다, 클래스가 순환 방식으로 상속되는 경우 문제를 일으킬 수 있다.

예시

Untitled

위 그림과 같이 A가 최상위 부모 클래스이고, B 와 C 가 A로 상속받는 자식클래스일때 또 B와 C를 다중상속받는 D가 존재 할때의 상황이라고 가정하면 여기서 문제가 발생한다. 만약 A클래스에 가상함수가 존재하여 B,C에서 오버라이드해서 재정의를 했을때, D가 그 오버라이드한 함수를 호출할 때 발생한다. 이러한 모호함은 예측할 수 없는 동작과 컴파일 오류로 이어질수도 있다.

이러한 현상을 죽음의 다이아몬드라고 한다.

Untitled

또한 virtual 함수를 오버라이드 했지만 그 상위의 부모함수를 부르고 싶을수도 있다. 하지만 각각 부모의 함수를 가지고 있기 때문에 이름만 가지고 호출할 수 없다. 따라서 이런 상황에서는 해당 클래스의 네임스페이스를 붙여서 명시적으로 호출 해야한다.

MiddleDerivedOne::SimpleFunc();
//MiddleDerivedOne클래스가 상속한 Base클래스의 SimpleFunc함수호출을 명령
MiddleDerivedTwo::SimpleFunc();
//MiddleDerivedTwo클래스가 상속한 Base클래스의 SimpleFunc함수호출을 명령

그런데 이러한 상황에서, Base클래스의 멤버가 LastDerived객체에 하나씩만 존재하는 것이 타당한 경우가 대부분이다.

해결 방법

위 그림에서 Base클래스는 한번만 상속받는게 더 현실적인 해결책이 될수 있다.그리고 이를 위한 문법이 가상 상속이다.

class MiddleDerivedOne : virtual public Base {...}
class MiddleDerivedTwo : virtual public Base {...}

<aside> 💡 언리얼C++에서는 이러한 현상을 막고자 Super 키워드 로 부모를 부를수 있도록 클래스의 다중상속을 막고있다 (그렇기 때문에 언리얼엔진에서는 Super로 부모의 virtual함수를 호출 할 수 있다. 별도의 인터페이스로 부터의 다중상속을 하는 방식으로 구현하도록 되어있다.

</aside>