본문 바로가기
Object Oriented Programming(C++)/Effective C++

Effective C++ | 항목 40 다중 상속은 심사숙고해서 사용하자

by continue96 2024. 8. 6.

Effective C++ 항목 40

 

항목 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 상속을 받는 경우에 적합합니다.

댓글