다중 상속은 하나의 클래스가 두 개 이상의 기본 클래스의 인터페이스와 구현을 상속할 수 있게 해주는 기능입니다. 이는 C++의 강력한 특징으로, 언어의 초기부터 복잡한 아키텍처를 구현하기 위해 널리 사용되었습니다.
문제의 역사: 다중 상속은 재사용 가능한 컴포넌트를 만들고 다양한 역할을 하나의 클래스에 통합하기 위한 수단으로 C++에 추가되었습니다 (예: 객체가 동시에 스레드이자 큐인 경우).
문제: 다중 상속에서의 주요 문제는 '다이아몬드 문제' (다형성 상속 문제), 기본 클래스의 멤버에 대한 불명확한 접근, 생성자/소멸자의 호출 순서에 대한 불확실성입니다.
해결 방법: 위의 문제를 피하기 위해 C++에서는 가상 상속이 제공됩니다. 이는 여러 경로가 동일한 조상을 가리킬지라도 해당 조상이 단 한 번만 생성되도록 보장하며, 초기화/파괴 순서를 올바르게 처리합니다.
코드 예시:
class A { public: int value; A() : value(1) {} }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; int main() { D d; d.value = 10; // OK, A는 하나만 존재 return 0; }
주요 특징:
기본 클래스가 두 번 상속될 경우 (왼쪽과 오른쪽), 객체의 메모리에 몇 개의 복사본이 있을까요?
기본적으로 두 개입니다. 가상 상속을 사용하지 않는 경우에만 해당됩니다. 가상 상속이 있을 경우 정확히 하나의 복사본만 존재합니다.
모호성이 발생할 경우, 멤버 접근이 어떤 기본 클래스에 해당되는지 명시할 수 있습니까?
예, 한정자를 사용하여 할 수 있습니다:
d.B::value = 5; d.C::value = 6;
다중 상속의 경우 생성자와 소멸자의 호출 순서는 어떻게 결정되나요?
생성자의 호출 순서는 상속 목록에서 기본 클래스의 선언 순서(왼쪽에서 오른쪽)와 그 다음으로 파생 클래스의 순서를 따릅니다. 소멸자는 반대 순서입니다.
프로그래머가 다중 상속을 통해 로깅 및 큐 시스템을 구현하고 다이아몬드 문제에 대해 알지 못합니다. 그 결과, 공통 로거가 두 번 초기화되어 리소스 해제 시 충돌이 발생합니다.
장점:
단점:
공통 로거를 위해 가상 상속을 사용하고 클래스 멤버가 생성자에서 명시적으로 초기화됩니다.
장점:
단점: