Skip to content

Commit

Permalink
📝 Concept of DeadlyDiamondOfDeath is posted.
Browse files Browse the repository at this point in the history
  • Loading branch information
soo-bak committed Feb 11, 2024
1 parent f53b832 commit e353143
Showing 1 changed file with 134 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
layout: single
title: "죽음의 다이아몬드(DDD, the Deadly Diamond of Death) - soo:bak"
date: "2024-02-12 00:58:00 +0900"
---
<br>

## 죽음의 다이아몬드(DDD, the Deadly Diamond of Death)
`죽음의 다이아몬드` 는 프로그래밍에서 `다중 상속` 을 사용할 때 발생할 수 있는 복잡한 문제를 지칭하는 용어. <br>
<br>
특히, `C++` 와 같이 다중 상속을 허용하는 언어에서 다중 상속을 사용할 때 자주 발생하는 문제.<br>
<br>
<br>
<br>

## 죽음의 다이아몬드 란?
`죽음의 다이아몬드` 는 클래스 상속 구조에서,<br>
<br>
<b>'한 클래스가 두 개 이상의 클래스로부터 상속을 받고, 이러한 기반 클래스들이 공통의 조상을 가지고 있을 때'</b> 발생하는 문제이다.<br>
<br>
<br>
예를 들어, 다음과 같은 클래스 구조에서 :<br>
<br>

```css
Base
/ \
A B
\ /
C
```
<br>
여기서, 클래스 `C` 는 기반 클래스 `A` 와 기반 클래스 `B` 로부터 상속을 받고, <br>
<br>
클래스 `A` 와 클래스 `B` 는 기반 클래스 `Base` 로부터 상속을 받는다.<br>
<br>
<br>
이 때, 만약 `Base` 클래스에 `soobak` 이라는 함수가 정의되어 있고, `C` 클래스의 객체에서 이 함수를 호출하려고 하면, <br>
<br>
`C` 가 `A` 의 `soobak` 을 호출해야 하는지, 아니면 `B` 의 `soobak` 을 호출해야하는지 명확하지가 않다.<br>
<br>
<br>

### 문제의 심화
이 문제는 단순히 '어떤 함수를 호출할 것인가?' 에 대한 결정에 대해서 뿐만 아니라, <br>
<br>
`Base` 클래스의 `인스턴스` 가 `C` 객체 내에 두 번 생성될 가능성을 내포하고 있다는 점에서 더욱 큰 문제가 된다.<br>
<br>
이는, 리소스 낭비와 데이터의 불일치 등 다양한 문제들을 초래할 수 있으며, 프로그램의 예측 불가능한 동작을 일으킬 수 있다.<br>
<br>

### C++ 에서의 해결 방법
`C++` 에서는 이러한 문제를 해결하기 위해 `가상 상속(Virtual Inheritance)` 을 도입하였다.<br>
<br>
`가상 상속` 을 사용하면, <b>공통의 조상 클래스가 다중 상속 구조에서 단 한 번만 인스턴스화</b> 된다.<br>
<br>
<br>

<b>[가상 상속에 대한 예시 코드]<br></b>

```c++
class Base {
public :
void soobak() {
// 구현...
}
};

class A : virtual public Base { // virtual 키워드로 가상 상속
// A 클래스의 구현
};

class B : virtual public Base { // virtual 키워드로 가상 상속
// B 클래스의 구현
};

class C : public A, public B{
// C 클래스의 구현
};
```
<br>: 여기서, `A``B` 클래스는 `Base` 로부터 가상으로 상속을 받는다.<br>
<br>
이로 인해, `C` 객체 내에서 `Base` 클래스의 단일 인스턴스만 존재하게 되며,<br>
<br>
`C` 객체를 통해 `Base` 의 함수에 접근할 때 <b>모호함이 해결</b>된다.<br>
<br>
<br>

### 가상 상속의 주의점
가상 상속을 사용할 때는 몇 가지 주의점이 있다.<br>
<br>
우선, 첫 번째로 <b>가상 상속은 일반 상속에 비하여 오버헤드가 더 크므로</b>, 반드시 필요한 경우에만 사용해야 한다.<br>
<br>
두 번째로, `가상 기반 클래스의 생성자``가장 파생된 클래스에서만 직접 호출할 수 있다` 는 점이다.<br>
<br>
이는 가상 상속 구조에서 기반 클래스의 초기화 순서를 제어하기 위함이다.<br>
<br>
<br>
<br>

## 다중 상속과 함수 호출 스택 프레임
함수 호출 시, 스택 프레임은 호출된 함수의 매개변수, 지역 변수, 반환 주소 등의 정보를 포함한다.<br>
<br>
다중 상속 구조에서 특정 함수를 호출할 때, 어떤 상위 클래스의 함수가 호출될지 명확히 구분되지 않으면,<br>
<br>
스택 프레임의 생성과 관리에서 혼란이 발생할 수 있다.<br>
<br>
<br>

### '죽음의 다이아몬드' 와 스택 프레임
'죽음의 다이아몬드' 구조에서는 가장 하위에 있는 파생 클래스가 함수를 호출할 때, <br>
<br>
상속 받은 두 상위 클래스가 공통의 조상으로부터 같은 함수를 상속받았다면,<br>
<br>
<b>해당 함수를 스택에 어떻게 쌓을지 결정하기가 어렵다.</b><br>
<br>
이로 인하여, 같은 함수가 스택에 중복으로 쌓일 수 있으며, 메모리 낭비 및 실행 흐름의 혼란을 초래하게 되는 것이다.<br>
<br>
<br>

### 가상 상속과 스택 프레임의 안정성
가상 상속을 사용하면, 공통의 조상 클래스는 스택 상에서 '단 하나의 공유된 인스턴스' 만을 가지게 된다.<br>
<br>
따라서, 함수 호출 시 스택 프레임이 더욱 명확하고 효율적으로 관리될 수 있도록 한다.<br>
<br>

> 가상 상속을 사용할 때, 파생 클래스에서 조상 클래스의 함수를 호출하면,<br>
컴파일러는 '가상 상속 테이블' 을 참조하여 정확한 함수의 위치를 찾는다.<br>
이 과정을 통해 스택 프레임은 정확한 함수 호출 정보를 유지할 수 있으며,<br>
중복이나 혼란 없이 함수를 실행할 수 있다.<br>
<br>
<br>
<br>

0 comments on commit e353143

Please sign in to comment.