[모던C++입문] 6.3 다중 상속
- 📕 Book/모던C++입문
- 2021. 7. 30.
6.3 다중 상속
복수의 부모 클래스
- 클래스는 여러 슈퍼 클래스에서 파생될 수 있다.
class student
{
virtual void all_info() const
{ cout << "[student] My name is " << name << endl; }
...
}
class mathematician
{
virtual void all_info() const
{ cout << "[mathman] My name is " << name << endl; }
...
}
class math_student : public student, public mathematician
{
//all_info를 정의하지 않으면 모호하게 상속된다
}
int main()
{
math_student bob("Robert Robson", "Algebra", "Fermat's Last Theorem");
bob.all_info();
//오류 : all_info 함수가 모호하다
}
공통의 조부모
중복성과 모호함
- 앞선 mathematician과 student에게 person이라는 슈퍼클래스를 추가해보자
class person
{
virtual void all_info() const
{ cout << "[person] My name is " << name << endl; }
...
};
class student : public person
{ ... }
class mathematician : public person
{
virtual void all_info() const
{
person::all_info();
}
}
class math_student : public student, public mathematician
{
virtual void all_info() const override
{
student::all_info();
mathematician::all_info();
}
}
int main()
{
math_student bob("Robert Robson", "Algebra", "Fermat's Last Theorem");
bob.all_info();
//다음과 같이 출력된다
//[student] My name is Rovert Robson
//[person] My name is Rovert Robson
}
- 중복성 : 위의 코드는 person의 name을 두번 저장한다.
- 오류 발생 쉬움 : name의 두 값이 일치 하지 않을 수 있음
- 모호함 : math_student 에서 person::name에 접근할때 모호함
가상 베이스 클래스
- 가상 베이스 클래스(Virtual Base Class)를 사용하면 공통 슈퍼 클래스에 멤버를 한번만 저장한다.
class person { ... };
class student : public virtual person { ... };
class mathematician : public virtual person { ... };
class math_student : public student, public mathematician
{
public:
math_student(const string& name, const string& passed, const string& proved) :
student(name, passed), mathematician(name, proved) { }
...
}
int main()
{
math_student bob("Robert Robson", "Algebra", "Fermat's Last Theorem");
bob.all_info();
//다음과 같이 출력된다
//[student] My name is
// I passed the following grades: algebra
// I proved: Fermat's Last Theorem
}
- person 클래스의 생성자를 호출하는 동작은 가장 나중에 파생된 math_student 클래스에게 전가한다.
- 그래서 mathematician과 student에서 person생성자를 호출하는 동작은 비활성화 된다
- 따라서 person 생성자가 호출되지 않았고, name에 이름이 초기화 되지 못했다
class student : public virtual person
{
student(const string& passed) : passed(passed) { }
...
};
class mathematician : public virtual person
{
mathematician(const string& proved) : proved(proved) { }
...
};
class math_student : public student, public mathematician
{
public:
math_student(const string& name, const string& passed, const string& proved) :
person(name), student(passed), mathematician(proved) { }
...
}
- 위와 같이 수정하여 person을 명시적으로 초기화해 name을 수정할 수 있게된다.
반응형