7. 가상 상속(virtual inheritance)과 다이아몬드 상속

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// ============================================================================
// [언어 내부동작 문제] C++ - 가상 상속(virtual inheritance)과 다이아몬드 상속
// ----------------------------------------------------------------------------
// 주제: 다이아몬드 상속에서 가상 상속이 기반 서브객체 개수, 멤버 접근 모호성, 생성 순서,
//       객체 레이아웃(vptr/vbase)과 sizeof 에 어떻게 영향을 주는지.
//
// 아래는 Base 를 가상 상속하는 L, R 과 둘을 함께 상속하는 D 다.
//
// 과제(코드를 고치는 문제가 아니라, 출력과 내부 동작을 예측·설명하는 문제):
//   1) D d; 를 만들 때 생성자 호출 순서(출력)를 예측하라. 누가 Base 를 생성하는가?
//   2) 가상 상속일 때 D 안에는 Base 서브객체가 몇 개 있는가? 만약 ': virtual Base' 의
//      virtual 을 빼면(비가상 상속) 개수와 d.x 접근은 어떻게 달라지는가?
//   3) d.x = 5; 가 모호하지 않은(혹은 모호한) 이유를 설명하라.
//   4) 가상 상속이 객체 레이아웃에 무엇을 추가하며(vptr/가상 기반 오프셋), 그것이
//      sizeof 와 멤버 접근 비용에 어떤 영향을 주는지 설명하라.
//   (먼저 직접 예측을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================

#include <iostream>

struct Base {
    int x = 1;
    Base()  { std::cout << "Base()\n"; }
    virtual ~Base() = default;
    virtual void who() { std::cout << "who: Base\n"; }
};

struct L : virtual Base {
    L() { std::cout << "L()\n"; }
};

struct R : virtual Base {
    R() { std::cout << "R()\n"; }
};

struct D : L, R {
    D() { std::cout << "D()\n"; }
};

int main() {
    D d;
    d.x = 5;                          // Base 서브객체가 하나이므로 모호하지 않다
    std::cout << "x=" << d.x << "\n";
    d.who();
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.