일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Unity
- C언어 포인터
- c#
- c언어
- 도커
- 깃
- c# winform
- 플러터
- 포인터
- Houdini
- c# 추상 클래스
- jupyter
- 구조체
- git
- Python
- gitlab
- jupyter lab
- C# delegate
- Flutter
- HTML
- docker
- 다트 언어
- Algorithm
- dart 언어
- github
- c# 윈폼
- C++
- Data Structure
- 유니티
- vim
- Today
- Total
nomad-programmer
[Programming/C++] 다중 상속(Multiple Inheritance) 본문
다중 상속(Multiple Inheritance)은 두 개 이상의 부모 클래스를 동시에 상속하는 경우를 말한다.
왜 다중 상속을 사용해야 할까
학생 정보를 관리하는 프로그램을 작성한다고 하자. 기본적으로 학부생과 대학원생의 정보를 관리하는 2개의 클래스를 생각해볼 수 있다. 그리고 기숙사생의 정보를 관리하는 클래스도 생각해볼 수 있다.
그렇다면 학부생이면서 동시에 기숙사생인 학생의 정보는 어떤 클래스에 의해서 관리되어야 할까. 학부생 클래스 아니면 기숙사생 클래스?
바로 이런 경우에 다중 상속을 사용할 수 있다. 학부생 클래스와 기숙사생 클래스를 모두 상속해서 학부생이면서 기숙사생인 학생의 정보를 관리하는 클래스를 만들 수 있다.
다중 상속의 사용
다음 예제에는 세 개의 클래스가 등장한다. 각각 학부생 클래스, 기숙사생 클래스 그리고 이 두 클래스를 다중 상속한 클래스다.
#include <iostream>
#include <string>
using namespace std;
// 학부생 클래스
class UnderGradStudent{
public:
string name; // 이름
string department; // 학부
};
// 기숙사생 클래스
class DormStudent{
public:
string building; // 기숙사 명
int roomNumber; // 방번호
};
// 기숙사생이면서 학부생인 경우
class UnderGrad_DormStudent : public UnderGradStudent, public DormStudent{
};
int main(int argc, const char * argv[]) {
UnderGrad_DormStudent st;
st.name = "ethan";
st.department = "Computer Engineering";
st.building = "ABC";
st.roomNumber = 555;
return 0;
}
충돌 회피하기
두 개의 부모 클래스에 동일한 이름의 멤버가 있는 경우에는 어떻게 될까? 다음 예제에서는 두 개의 부모 클래스가 ShowInfo()이라는 동일한 이름의 멤버 함수를 갖는 경우이다.
#include <iostream>
#include <string>
using namespace std;
// 학부생 클래스
class UnderGradStudent{
public:
string name; // 이름
string department; // 학부
void ShowInfo(){}
};
// 기숙사생 클래스
class DormStudent{
public:
string building; // 기숙사 명
int roomNumber; // 방번호
void ShowInfo(){}
};
// 기숙사생이면서 학부생인 경우
class UnderGrad_DormStudent : public UnderGradStudent, public DormStudent{
};
int main(int argc, const char * argv[]) {
UnderGrad_DormStudent st;
st.name = "ethan";
st.department = "Computer Engineering";
st.building = "ABC";
st.roomNumber = 555;
st.ShowInfo();
return 0;
}
컴파일 에러가 발생했다. "Member 'ShowInfo' found in multiple base classes of different types".
main함수에서 ShowInfo함수를 호출한다. 그런데 st 객체에는 두 개의 ShowInfo() 함수가 존재한다. 컴파일러는 이 둘 중 어떤 함수를 호출해야 할 지 모르기 때문에 오류를 발생시킨다.
이런 경우에는 의도를 구체적으로 밝혀줄 필요가 있다. 예를 들어 UnderGradStudent 클래스의 ShowInfo() 멤버 함수를 호출하기를 원한다면 다음과 같이 호출해주면 된다.
st.UnderGradStudent::ShowInfo();
컴파일러는 이제 어느 함수를 호출해야 할지 알 수 있고 에러를 발생시키지 않는다.
상속에서 가장 중요한 것은 자식 클래스가 부모 클래스의 모든 멤버를 상속 받는다는 점이다. 이 점만 잘 기억하고 있다면 상속과 관련해서 문제될 것은 없다.
포함과 상속을 구분해서 사용하기
포함과 상속은 기존에 만들어진 클래스를 재사용한다는 공통점을 가지고 있다. 이미 만들어진 클래스를 사용해서 새로운 클래스를 만들고자 할 때 포함을 사용해야 할지 상속을 사용해야 할지 결정하기 힘든 경우에는 다음의 가이드라인이 도움이 될 것이다.
- 포함은 has-a 관계이다. A가 B를 가지고 있따면(has) 포함을 사용하라.
- 상속은 is-a 관계이다. A가 B라면(is) 상속을 사용하라.
has-a 관계의 대표적인 예는 자동차와 타이어다. 자동차는 타이어를 가지고 있다(has). 하지만 자동차는 타이어가 아니다. 그렇기 때문에 자동차가 타이어를 포함하게 만드는 것이 옳다.
is-a 관계의 대표적인 예는 사과와 과일이다. 사과는 과일이다(is). 하지만 사과가 과일을 가지고 있는 것은 아니다. 그래서 사과는 과일을 상속 받게 만드는 것이 옳다.
또 한가지 예를 들자면, 사각형은 점을 가지고 있다(has). 사각형은 점이 아니다. 그렇기 때문에 포함하는 것이 옳다.
'Programming > C++' 카테고리의 다른 글
[Programming/C++] 가상 함수를 사용한 다형성의 구현 (0) | 2023.01.21 |
---|---|
[Programming/C++] 전역 함수를 이용한 연산자 오버로딩 (2) | 2023.01.20 |
[Programming/C++] 접근 제어 키워드 (public, protected, private) (0) | 2023.01.20 |
[Programming/C++] 연산자 오버로딩 (0) | 2023.01.19 |
[Programming/C++] const 멤버 함수와 비 const 멤버 함수 (0) | 2023.01.19 |