다이아몬드 상속 문제가 있고 가상 상속을 수행하는 경우 기본 클래스 중 하나만 생성되지만 실제로 어떻게 표현되는지 이해합니다.가상 기본 클래스는 어떻게 저장됩니까?
vtable에는 기본 클래스에 대한 포인터가 있으며 파생 클래스 중 하나가 생성되면 해당 포인터가 이미 있는지 확인하고 그렇지 않으면 기본 클래스를 가리 킵니다.
다이아몬드 상속 문제가 있고 가상 상속을 수행하는 경우 기본 클래스 중 하나만 생성되지만 실제로 어떻게 표현되는지 이해합니다.가상 기본 클래스는 어떻게 저장됩니까?
vtable에는 기본 클래스에 대한 포인터가 있으며 파생 클래스 중 하나가 생성되면 해당 포인터가 이미 있는지 확인하고 그렇지 않으면 기본 클래스를 가리 킵니다.
바로 시작합니다. 구현 세부 사항은 다를 수 있지만 실제로 기본 클래스를 찾기에 충분한 vtable (또는 어쨌든 클래스 메타 데이터) 정보가 있습니다.
AFAIK에는 구현시 포인터가 이미 있는지를 확인할 수 없습니다. C++은 가장 많이 파생 된 클래스를 모든 가상 기반을 구성하는 데 사용합니다. 그래서 보통의 다이아몬드 상속 Root
, Middle1
, Middle2
및 MostDerived
참여와, 코드의 인스턴스를 구축 방출 MostDerived
것이다 :
Root
을 구성하고 Middle1
을 구성 MostDerived
Middle2
MostDerived
MostDerived
나는 때문에 Middle1
의 구성 부품 Root
기본 클래스를 사용할 수 있지만 Middle1
의 가상 함수가 아직 MostDerived
에 정의 오버라이드 (override)를 참조을하지 않는 동안, 오히려 "는 vptr에서"보다 "는 vptr에서"를 말한다 . 이를 해결하기 위해 구현에 달렸습니다. 오브젝트 크기를보고 얼마나 많은 숨겨진 포인터를 사용했는지, 그리고 숫자가 Middle1
에 가상 함수가 있는지 여부에 따라 달라 지는지 직접 실험 해 볼 수 있습니다. 일반적인 코드의 인스턴스를 구성하는 발광 것을
참고 Middle1
것이다
Root
및 Middle1
Middle1
Middle1
의 생성자입니다. 우리가 MostDerived
의 Middle1
기본 클래스 하위 개체를 구성 할 때는, 우리는 그 단계, 모든 세 가지 중 두 가지를하고 싶다. 이러한 이유로 두 개 이상의 생성자가있는 클래스에 대해 생성 된 코드에는 여러 생성자가 포함되어 있습니다. 하나는 가장 파생 유형이 클래스 인 객체이고 다른 하나는 유형이 클래스 인 기본 클래스 하위 객체입니다. .
가끔 가상베이스를 구성할지 여부를 말하는 추가 함수 매개 변수. – aschepler
@aschepler : 충분합니다. 결정적으로 표준은 생성자에 대한 포인터를 가져 오지 못하기 때문에 구현은 호출 규칙, 다중 진입 점 또는 추가 매개 변수로 좋아하는 트릭을 재생할 수 있습니다.가상 기본 코드에서 일반 생성자의 나머지 부분으로 떨어지는 것은 명백한 전략입니다. –
[필수 읽기] (http://www.phpcompiler.org/articles/virtualinheritance.html). 짧은 대답 : 마술과 함께. –