일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- std::ostream
- 더 지니어스 양면포커
- std::cout
- dynamic_cast
- operator overloading
- this call
- suffix return type
- virtual function
- std::endl
- virtual destructor
- conversion constructor
- delete function
- base from member
- vector size
- placement new
- std::vector
- member function pointer
- return by reference
- virtual function table
- diamond inheritance
- virtual inheritance
- c++ basic practice
- pointer to member data
- vector capacity
- C++
- new&delete
- discord bot
- increment operator
- c++ multi chatting room
- constructor
- Today
- Total
I'm FanJae.
[C++] Multiple Inheritance, Diamond Inheritance, Virtual Inheritance 본문
[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 |