[C++] 9-2. 다중상속(Multiple Inheritance)에 대한 이해

2024. 11. 22. 14:15·공부/C++
728x90

다중상속이란, 둘 이상의 클래스를 동시에 상속하는 것을 말한다.

일반적인 경우에서 다중상속은 다양한 문제를 동반한다.

따라서 가급적 사용하지 않는것이 좋지만, 예외적으로 매우 제한적인 사용까지 부정할 필요는 없다..

 


다중상속의 모호성(Ambiguous)

다중상속의 대상이 되는 두 기초클래스에 동일한 이름의 멤버가 존재하는 경우에는 문제가 발생할 수 있다.

유도 클래스 내에서 멤버의 이름만으로 접근이 불가능하기 때문이다.

#include <iostream>
using namespace std;

class BaseOne
{
public:
	void SimpleFunc() { cout << "BaseOne" << endl; }
};

class BaseTwo
{
public:
	void SimpleFunc() { cout << "BaseTwo" << endl; }
};

class MultiDerived : public BaseOne, protected BaseTwo
{
public:
	void ComplexFunc() {
		//두 클래스에 정의된 멤버함수의 이름이 동일하다.
		BaseOne::SimpleFunc();
		BaseTwo::SimpleFunc();
	}
};

int main(void) {
	MultiDerived mdr;
	mdr.ComplexFunc();
	return 0;
}

 


가상 상속(Virtual Inheritance)

#include <iostream>
using namespace std;

class Base {
public:
	Base() { cout << "Base Constructor" << endl; }
	void SimpleFunc() { cout << "BaseOne" << endl; }
};

class MiddleDerivedOne : virtual public Base //가상 상속
{
public:
	MiddleDerivedOne() : Base() {
		cout << "MiddleDerivedOne Constructor" << endl;
	}
	void MiddleFuncOne()
	{
		SimpleFunc();
		cout << "MiddleDerivedOne" << endl;
	}
};

class MiddleDerivedTwo : virtual public Base //가상 상속
{
public:
	MiddleDerivedTwo() : Base()
	{
		cout << "MiddleDerivedTwo Constructor" << endl;
	}
	void MiddleFuncTwo()
	{
		SimpleFunc();
		cout << "MiddleDerivedTwo" << endl;
	}
};

class LastDerived : public MiddleDerivedOne, public MiddleDerivedTwo
{
public:
	LastDerived() : MiddleDerivedOne(), MiddleDerivedTwo()
	{
		cout << "LastDerived Constructor" << endl;
	}
	void ComplexFunc()
	{
		MiddleFuncOne();
		MiddleFuncTwo();
		SimpleFunc();
	}
};

int main(void) {
	cout << "객체생성 전 ...." << endl;
	LastDerived ldr;
	cout << "객체생성 후 ...." << endl;
	ldr.ComplexFunc();
	return 0;
}

위 예제에서 보이는 상속의 구조는 다음과 같다. 여기서 중요한 것은 LastDerived 클래스가 Base 클래스를 간접적으로 두 번 상속한다는 점이다.

때문에 위 예제에서 virtual선언이 되지 않은 상태에서 객체가 생성되면 하나의 객체 내에 두 개의 Base 클래스 멤버가 존재하기 때문에 ComplexFunc 함수 내에서 이름만 가지고 SipleFunc 함수를 호출할 수는 없다.

따라서 이 경우에는 다음과 같이 어느 클래스를 통해서 간접 상속한 Base 클래스의 멤버함수를 호출할 것인지 명시해야 한다.

  • MiddleDerivedOne::SimpleFunc();
  • MiddleDerivedTwo::SimpleFunc();

그런데 이런 상황에서, Base 클래스를 딱 한번만 상속하게끔 하는 것이 더 현실적인 해결책이 될 수 있다.

이를 위한 문법이 바로 '가상 상속'이다.

  • class MiddleDerivedOne : virtual public Base { };
  • class MiddleDerivedTwo : virtual public Base { };
  • class LastDerived : public MiddleDerivedOne, public MiddleDerivedTwo{   };

이렇게 하면 LastDerived 객체 내에는 MiddleDerivedOne 클래스와 MiddleDerivedTwo 클래스가 동시에 상속하는 Base 클래스의 멤버가 하나씩만 존재하게 된다.

 

따라서 위 예제에서는 SimpleFunc 함수를 이름만 가지고 호출할 수 있는것이다.

그리고 예제의 실행 결과를 보면 실제로 Base 클래스의 생성자가 한번만 호출되는 것을 확인할 수 있다.

(만약 가상 상속을 하지 않는다면, Base 클래스의 생성자는 두 번 호출된다.)

728x90

'공부 > C++' 카테고리의 다른 글

[C++] 10-2. 단항 연산자의 오버로딩  (0) 2024.11.25
[C++] 10-1. 연산자 오버로딩의 이해와 유형  (0) 2024.11.25
[C++] 9-1. 멤버 함수와 가상 함수의 동작 원리  (0) 2024.11.21
[C++] 08-4. OOP 단계별 프로젝트 06단계  (0) 2024.11.18
[C++] 8-3.가상 소멸자와 참조자의 참조 가능성  (0) 2024.11.15
'공부/C++' 카테고리의 다른 글
  • [C++] 10-2. 단항 연산자의 오버로딩
  • [C++] 10-1. 연산자 오버로딩의 이해와 유형
  • [C++] 9-1. 멤버 함수와 가상 함수의 동작 원리
  • [C++] 08-4. OOP 단계별 프로젝트 06단계
knhoo
knhoo
  • knhoo
    &*
    knhoo
  • 전체
    오늘
    어제
    • 전체 (139)
      • Unity 개발일지 (1)
        • [Unity2D]졸업프로젝트 (17)
        • [Unity3D]VR프로젝트 (2)
      • 공부 (115)
        • 부트캠프 (12)
        • C++ (39)
        • Unity & C# (8)
        • 데이터베이스 (2)
        • 컴퓨터비전 (0)
        • 컴퓨터구조 (0)
        • python (7)
        • BAEKJOON (36)
        • 개발 (2)
        • 자료구조 (9)
      • 일상 (2)
  • 블로그 메뉴

    • Github
    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 📖README
  • 인기 글

  • 태그

    앱테크
    c#
    백준
    오블완
    캐시워크
    머니워크
    C++
    비트버니
    til
    백준 #python
    unity2d
    Python
    unity
    멋쟁이사자처럼후기
    Cpp
    패널파워
    구간합
    야핏무브
    자료구조
    티스토리챌린지
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
knhoo
[C++] 9-2. 다중상속(Multiple Inheritance)에 대한 이해
상단으로

티스토리툴바