I'm FanJae.

[C++] Multiple Inheritance, Diamond Inheritance, Virtual Inheritance 본문

C++/Basic

[C++] Multiple Inheritance, Diamond Inheritance, Virtual Inheritance

FanJae 2024. 8. 23. 11:31

※ 본 포스트는 코드누리 C++ Basic 강의 내용을 보고 정리한 포스트입니다.

 

1. 다중 상속(Multiple Inheritance)이란?

class InputFile
{
public:
    void read() {}
};

class OutputFile
{
public:
    void write() {}
};

class IOFile : public InputFile, public OutputFile
{
};

int main()
{
    IOFile file;
    file.open();
}

- 클래스가 2개 이상의 기반 클래스로부터 상속 되는 것

- C++,Lisp, Curl 등은 이를 지원하지만, Java, C# 등은 다중 상속을 지원하지 않는다.

 

1-1. 다중 상속의 문제점

- 서로 다른 기반 클래스에 동일 이름의 멤버가 있을때 충돌 한다.

class InputFile
{
public:
    void read() {}
    void open() {}
};

class OutputFile
{
public:
    void write() {}
    void open() {}
};

class IOFile : public InputFile, public OutputFile
{
};

int main()
{
    IOFile file;
    file.open(); // Ambiguous 오류
    file.InputFile::Open(); // 이렇게 쓰면 해결할 수 있기는 하다.
}

- 위와 같이 쓰면 해결 할 수 있지만, 그렇게 좋은 상황은 아니다.

- 이외에도, 다이아몬드 상속(Diamond Inheritance) 문제가 존재한다.

 

1-2.다이아몬드 상속(Diamond Inheritance)이란?

 

class File
{
public:
    std::string filename;
    void open() {}
};

class InputFile : public File
{
public:
    void read() {}
    void open() {}
};

class OutputFile : public File
{
public:
    void write() {}
};

class IOFile : public InputFile, public OutputFile
{
};

int main()
{
    IOFile file;
    file.open(); // Ambiguous 오류
    file.InputFile::Open(); // 이렇게 쓰면 해결할 수 있기는 하다.
}

- 이 상속 구조에 대한 다이어그램을 그려보면 아래와 같을 것이다.

- 이렇게 볼때는 크게 이상해보이지 않을 수 있으나, 객체를 생성해보면, 이와 같이 만들어진다.

- InputFile과 OutputFile이 모두 File을 상속 받음에 따라서, 2개나 할당되어 있는 것을 확인할 수 있다.

- 만약, open()을 호출 했다면, Inputfile과 OutputFile의 Filename중 어떤 것을 사용해야 하는가?

- C++ 에서는 이를 해결 해주는 기능이 Virtual 상속이다.

 

1-3. 가상 상속(Virtual Inheritance)

- Virtual Inheritance를 사용하면 기본 클래스의 인스턴스를 한 번만 생성되게 만들어 준다.

class File
{
public:
    std::string filename;
    void open() {}
};

class InputFile : virtual public File
{
public:
    void read() {}
    void open() {}
};

class OutputFile : virtual public File
{
public:
    void write() {}
};

class IOFile : public InputFile, public OutputFile
{
};

int main()
{
    IOFile file;
    file.open(); // Ambiguous 오류
    file.InputFile::Open(); // 이렇게 쓰면 해결할 수 있기는 하다.
}

- 다음과 같이 객체가 생성됨을 확인할 수 있다. 

- 기존 InputFile과 OutputFile에서 File 객체가 2개 만들어지지 않고, 1개만 만들어지는 것을 확인할 수 있다.

 

다이아몬드 상속(Diamond Inheritance)는 특정한 상황에 따라서 절대 피할 수 없는 경우도 존재한다. 하지만, 가급적 클래스 디자인을 잘하여 다이아몬드 상속 구조를 만들지 않는것이 좋고, 만들어야 한다면 가상 상속(Virtual Inheritance)를 이용하여 해결해야 한다.

 

'C++ > Basic' 카테고리의 다른 글

[C++] Operator Overloading II  (0) 2024.08.24
[C++] Operator Overloading I  (0) 2024.08.23
[C++] RTTI, Dynamic Cast  (0) 2024.08.22
[C++] Virtual Function Table  (0) 2024.08.22
[C++] Abstract class, Interface  (0) 2024.08.21
Comments