다중 상속 (Multiple Inheritance)

강일모·2022년 11월 16일
0

다중 상속 (Multiple Inheritance)

다중 상속 (Multiple Inheritance) 은 두 개 이상의 클래스를 상속받는 것을 이야기합니다.

다중 상속 시 발생할 수 있는 문제점들에 대해 알아보겠습니다.

  1. 여러 클래스를 상속 받기 때문에 메소드나 멤버 변수의 이름이 중복으로 지정되어 있을 수 있습니다.

이를 해결하기 위해서 Scope resolution operator(::) 를 사용할 수 있습니다.

위 코드를 살펴보면 클래스 C는 class A와 class B를 상속받습니다. class A와 class B에는 모두 func라는 이름의 메소드가 존재합니다. 따라서 클래스 C에서 func를 구분해서 사용하기 위해 c.B::func();. c.A::func(); 와 같이 scope resolution operator를 사용해주어 ambiguities를 해결해 줄 수 있습니다.

  1. Dreaded Diamond Inheritance Pattern

Dreaded Diamond Inheritance 는 상속 과정에서 하나의 클래스가 두 번 이상 호출되는 경우를 이야기합니다.

그림과 같은 상속 관계를 가지는 클래스들을 생각해봅시다.
클래스 D는 B와 C를 상속 받습니다. 그리고 B와 C는 모두 A를 상속 받아 만들어진 클래스이므로, 최종적으로 클래스 D는 A의 객체를 2번 가지게 되는 꼴이 됩니다. 이렇게 상속 과정에서 한 클래스가 두 번 이상 나타나는 경우를 Dreaded Diamond Inheritance Pattern 이라고 이야기합니다.

다음의 코드를 살펴보며 Dreaded Diamond Inheritance Pattern 의 문제점에 대해 자세히 이해해봅시다.

DogCat은 Cat과 Dog을, Cat과 Dog은 각각 Animal을 상속받고 있습니다.
다중 상속 시 코드에 명시된 순서대로 Constructor 가 Invoke 됩니다. 따라서 DogCat Class 의 Object 를 생성할 때에는 Animal -> Cat -> Animal -> Dog -> DogCat 순서로 Constructor 가 호출됩니다. 따라서 DogCat Object는 두 개의 Animal Object를 갖게되는 것입니다.

Animal Object를 두 개 갖게 되므로, DogCat의 메소드인 setAge() 를 호출 할 때, age 멤버 변수가 두 개의 Animal Object 중 어느 것인지 확정할 수 없게 되므로 에러가 발생하게 됩니다.

그리고 Animal = dat;의 코드에서 new DogCat()으로 생성한 객체를 가르키는 dat 포인터를 Animal 포인터인 animal 에 Upcasting 시에 DogCat이 가지는 Animal Object 중 어떤 것을 가르킬지 모호해지기 때문에 에러가 발생하게 됩니다.

따라서 static_cast<Cat > 또는 static_cast<Dog > 을 통해 어떤 클래스에 속한 Animal 객체를 지칭할 것인지 명시해주거나, Virtual Inheritance를 사용해서 해결해 줄 수 있습니다.

Virtual Inheritance에 대해서 알아보겠습니다.

Virtual Inheritance
Virtual Inheritance란 Base Class의 멤버 변수들을 단 하나의 복사본만을 GrandChild Dervied Class가 갖는 C++ 기술입니다.

Virtual Inheritance를 사용해 Dreaded Diamond Inheritance Pattern을 해결할 수 있습니다.

0개의 댓글