2013-06-07 5 views
1

다이아몬드 상속 문제가 있고 가상 상속을 수행하는 경우 기본 클래스 중 하나만 생성되지만 실제로 어떻게 표현되는지 이해합니다.가상 기본 클래스는 어떻게 저장됩니까?

vtable에는 기본 클래스에 대한 포인터가 있으며 파생 클래스 중 하나가 생성되면 해당 포인터가 이미 있는지 확인하고 그렇지 않으면 기본 클래스를 가리 킵니다.

+9

[필수 읽기] (http://www.phpcompiler.org/articles/virtualinheritance.html). 짧은 대답 : 마술과 함께. –

답변

1

바로 시작합니다. 구현 세부 사항은 다를 수 있지만 실제로 기본 클래스를 찾기에 충분한 vtable (또는 어쨌든 클래스 메타 데이터) 정보가 있습니다.

AFAIK에는 구현시 포인터가 이미 있는지를 확인할 수 없습니다. C++은 가장 많이 파생 된 클래스를 모든 가상 기반을 구성하는 데 사용합니다. 그래서 보통의 다이아몬드 상속 Root, Middle1, Middle2MostDerived 참여와, 코드의 인스턴스를 구축 방출 MostDerived 것이다 :

  • Root을 구성하고 Middle1을 구성 MostDerived
  • 에 대한 vtable을 가리 키도록 vptr에서 설정하고 Middle2
  • 구성 데이터 멤버 MostDerived
  • MostDerived

나는 때문에 Middle1의 구성 부품 Root 기본 클래스를 사용할 수 있지만 Middle1의 가상 함수가 아직 MostDerived에 정의 오버라이드 (override)를 참조을하지 않는 동안, 오히려 "는 vptr에서"보다 "는 vptr에서"를 말한다 . 이를 해결하기 위해 구현에 달렸습니다. 오브젝트 크기를보고 얼마나 많은 숨겨진 포인터를 사용했는지, 그리고 숫자가 Middle1에 가상 함수가 있는지 여부에 따라 달라 지는지 직접 실험 해 볼 수 있습니다. 일반적인 코드의 인스턴스를 구성하는 발광 것을

참고 Middle1 것이다

  • 구조체 RootMiddle1
  • 신체 실행의 Middle1
  • 구조체 데이터 멤버에 대한 VTABLE 가리 키도록 vptr에서 설정할 Middle1의 생성자입니다. 우리가 MostDerivedMiddle1 기본 클래스 하위 개체를 구성 할 때

는, 우리는 그 단계, 모든 세 가지 중 두 가지를하고 싶다. 이러한 이유로 두 개 이상의 생성자가있는 클래스에 대해 생성 된 코드에는 여러 생성자가 포함되어 있습니다. 하나는 가장 파생 유형이 클래스 인 객체이고 다른 하나는 유형이 클래스 인 기본 클래스 하위 객체입니다. .

+0

가끔 가상베이스를 구성할지 여부를 말하는 추가 함수 매개 변수. – aschepler

+0

@aschepler : 충분합니다. 결정적으로 표준은 생성자에 대한 포인터를 가져 오지 못하기 때문에 구현은 호출 규칙, 다중 진입 점 또는 추가 매개 변수로 좋아하는 트릭을 재생할 수 있습니다.가상 기본 코드에서 일반 생성자의 나머지 부분으로 떨어지는 것은 명백한 전략입니다. –

관련 문제