virtual 상속은 왜 받는거에요?

virtual base class, virtual 상속은 왜 쓰는 거고 무슨 의미가 있는 건지 알고 싶습니다.

소스코드

class Foo
{
public:
    void DoSomething() { /* ... */ }
};

class Bar : public virtual Foo
{
public:
    void DoSpecific() { /* ... */ }
};

2답변

  • 좋아요

    1

    싫어요
    채택취소하기

    virtual 상속은 다중 상속에서 의미가 있습니다. virtual 상속을 함으로써 상속받은 클래스의 instance가 계층 구조 상에 여러 개 존재하는 것을 방지해줍니다.

    class A { public: void Foo() {} };
    class B : public A {};
    class C : public A {};
    class D : public B, public C {};
    

    위 코드의 계층구조를 간략하게 보면 밑과 같은 다이아몬드 구조가 나옵니다. D가 B, C를 상속받고 B와 C 모두 A를 상속받지요.

      A
     / \
    B   C
     \ /
      D
    

    이런 상황에서는 모호함이 발생합니다.

    D d;
    d.Foo(); // 이건 B의 foo일까요? C의 foo일까요?
    

    virtaul 상속은 이런 상황에서 쓰입니다. 클래스를 상속받을 때 virtual을 명시하면 컴파일러는 single instance만을 만듭니다.

    class A { public: void Foo() {} };
    class B : public virtual A {};
    class C : public virtual A {};
    class D : public B, public C {};
    

    이 계층구조는 이제 A의 인스턴스가 하나만 존재하지요. 더 이상 d.Foo(); 가 모호하지 않습니다.

    더 자세한 정보는 여기를 보세요.

  • virtual 상속은 다중 상속에서 의미가 있습니다. virtual 상속을 함으로써 상속받은 클래스의 instance가 계층 구조 상에 여러 개 존재하는 것을 방지해줍니다.

    class A { public: void Foo() {} };
    class B : public A {};
    class C : public A {};
    class D : public B, public C {};
    

    위 코드의 계층구조를 간략하게 보면 밑과 같은 다이아몬드 구조가 나옵니다. D가 B, C를 상속받고 B와 C 모두 A를 상속받지요.

      A
     / \
    B   C
     \ /
      D
    

    이런 상황에서는 모호함이 발생합니다.

    D d;
    d.Foo(); // 이건 B의 foo일까요? C의 foo일까요?
    

    virtaul 상속은 이런 상황에서 쓰입니다. 클래스를 상속받을 때 virtual을 명시하면 컴파일러는 single instance만을 만듭니다.

    class A { public: void Foo() {} };
    class B : public virtual A {};
    class C : public virtual A {};
    class D : public B, public C {};
    

    이 계층구조는 이제 A의 인스턴스가 하나만 존재하지요. 더 이상 d.Foo(); 가 모호하지 않습니다.

    더 자세한 정보는 여기를 보세요.

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.