항목 40 다중 상속은 심사숙고해서 사용하자
40.1 다중 상속의 단점
■ 40.1.1 다중 상속의 단점: 모호성
- 다중 상속은 여러 부모 클래스에서 똑같은 이름을 받는 경우, 모호성이 생긴다.
- C++는 최적으로 일치(best match)하는 함수를 먼저 찾고 그 함수의 접근 가능성을 확인한다.
- 따라서 멤버의 접근 제한자가 달라도 이름이 같으면 모호성이 발생한다.
■ 40.1.2 다중 상속의 단점: 데이터 멤버
- 다중 상속은 상위에 있는 여러 기본 클래스를 갖는 클래스 계통에서 발견된다.
- 죽음의 다이아몬드(deadly diamond) 모양이 나타날 수 있다.
- C++는 기본적으로 데이터 멤버를 중복으로 생성한다.
- 단, 가상 기본 클래스를 가상 상속(virtual inheritance)하는 경우 데이터 멤버를 중복으로 생성하지 않는다.
class File { ... };
class InputFile : public File { ... };
class OutputFile : public Flie { ... };
// File 클래스의 데이터 멤버를 중복해서 갖고 있습니다.
class IOFile : public InputFile, public OutputFile { ... };
// File 클래스를 가상 기본 클래스로 지정합니다.
class File { ... };
class InputFile : virtual public File { ... };
class OutputFile : virtual public Flie { ... };
// File 클래스의 데이터 멤버를 중복해서 갖고 있지 않습니다.
class IOFile : public InputFile, public OutputFile { ... };
■ 40.1.3 다중 상속의 단점: 메모리
- 다중 상속은 메모리를 더 많이 차지하고 속도가 더 느리다.
- 가상 상속하는 클래스로 생성된 객체의 크기는 그렇지 않은 것보다 더 크다.
- 가상 기본 클래스의 데이터 멤버에 접근하는 속도는 그렇지 않은 것보다 더 느리다.
■ 40.1.4 다중 상속의 단점: 초기화
- 다중 상속은 초기화가 번거롭다.
- 초기화해야 하는 가상 기본 클래스로부터 자식 클래스를 상속한 경우, 이 자식 클래스는 가상 기본 클래스가 있다는 사실을 염두해야 한다.
- 기존의 클래스 계통에 자식 클래스를 추가할 때, 이 자식 클래스는 가상 기본 클래스를 초기화해야 한다.
- 위와 같은 이유로 가상 기본 클래스를 굳이 쓸 이유가 없다면 쓰지 않는다. 가상 기본 클래스를 쓰는 경우, 가상 기본 클래스에는 최대한 데이터를 넣지 않는다.
40.2 다중 상속 예: 인터페이스 상속과 구현 상속 조합하기
- 객체 합성, 즉 구현의 private 상속과 인터페이스의 public 상속을 조합할 때 다중 상속을 사용할 수 있다.
class IPerson
{
public:
virtual std::string GetName() const = 0;
};
class PersonHelper
{
public:
virtual const char* GetPersonName() const;
virtual const char* GetOpenDelimeter() const;
virtual const char* GetCloseDelimeter() const;
};
class CPerson : public IPerson, private PersonHelper
{
public:
virtual std::string GetName() const { return PersonHelper::GetPersonName(); }
private:
virtual const char* GetOpenDelimeter() const { return ""; }
virtual const char* GetCloseDelimeter() const { return ""; }
};
NOTE
① 다중 상속은 모호성 발생, 가상 상속 필요, 크기 및 속도 비용 증가라는 문제가 있습니다.
② 다중 상속은 인터페이스 클래스로부터 public 상속을 받고 구현 클래스로부터 private 상속을 받는 경우에 적합합니다.
'Object Oriented Programming(C++) > Effective C++' 카테고리의 다른 글
Effective C++ | 항목 42 typename의 두 가지 의미를 제대로 파악하자 (0) | 2024.08.06 |
---|---|
Effective C++ | 항목 41 템플릿 프로그래밍은 암시적 인터페이스와 컴파일 시간 다형성부터 (0) | 2024.08.06 |
Effective C++ | 항목 39 private 상속은 심사숙고해서 구사하자 (0) | 2024.08.06 |
Effective C++ | 항목 38 has-a 혹은 is-implemented-in-terms-of를 모형화할 때는 객체 합성을 사용하자 (0) | 2024.08.06 |
Effective C++ | 항목 37 어떤 함수에 대해서도 상속받은 디폴트 인수는 절대로 재정의하지 말자 (0) | 2024.07.26 |
댓글