Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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 31
Archives
Today
Total
05-16 04:51
관리 메뉴

nomad-programmer

[Programming/C++] 다중 상속(Multiple Inheritance) 본문

Programming/C++

[Programming/C++] 다중 상속(Multiple Inheritance)

scii 2023. 1. 20. 01:57

다중 상속(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). 사각형은 점이 아니다. 그렇기 때문에 포함하는 것이 옳다.

Comments