는 그래서 가상 상속 static_cast
를 사용하여 다운 캐스트하는 것은 불가능하지만, 어떻게 다음 업 캐스팅 할 수 있습니다 :static_cast를 가상 상속에 어떻게 사용할 수 있습니까?
[ derived part | base part ]
나는 알고 upcasting 고려 : 개체의
class Base {...};
class Derived : public virtual Base {...};
...
Derived *d = new Derived();
Base *b = static_cast<Base*>(d);
메모리 레이아웃을 "안전"하지만 컴파일러는 상속이 가상 일 때 컴파일 타임에 기본 하위 객체에 대한 오프셋을 어떻게 알 수 있습니까? static_cast
은 vtable
을 사용합니까?
class Third : public Derived {...};
...
Derived *d = new Third(); // non-virtual upcast, no offset will be added
Base *b = static_cast<Base*>(d);
나도 같은 static_cast
라인을 사용하는이 시간이 있지만, 다른 인 Base
하위 개체에 오프셋 :
우리가 이런 일을 할 때 특히 혼란 (이것은 가상이 아니다 있습니다)! 개체의
메모리 레이아웃 : 그것은 d
지점에 객체의 실제 동적 타입에 의존하는 경우
[ derived part | third part | base part ]
그래서 어떻게이 컴파일시에 결정할 수있다? 당신이 경우에
Derived
에 대한 포인터가있을 때
대개 내가 알고있는 것으로부터 오프셋은 vtable에 저장됩니다. 그러나 컴파일 타임에 정적으로 수행되는 방법에 대한 대답은 없습니다. 내가 제공 한 두 가지 사례를 살펴보면 어느 vtable에 올바른 오프셋이 있는지에 대한 질문이 제기됩니까? 어느 것이 컴파일러에서보아야합니까, Derived의 vtable 또는 Third 's vtable입니까? 분명히 vtable의 2 개 오프셋이 다르므로 올바른 vtable을 선택하는 것이 실행 시간 유형에 달려 있습니다. 이것이 왜 정적으로 수행되었는지 이해할 수없는 이유입니다. –
static_cast에서 "static"은 컴파일 타임에 완료되었음을 의미하지 않습니다! 컴파일러가 컴파일 타임에 정보를 찾을 위치를 정적으로 파악할 수 있다는 것을 의미합니다. 예를 들어, vtable에서 오프셋을 검색하는 위치 또는 기본에 대한 포함 된 포인터가있는 위치를 알 수 있습니다 (가상 상속 구현 됨). 'dynamic_cast'처럼 vtable에서 어떤 클래스의 일치를 찾지 않을 것입니다. –
static_cast에는 동적 인 측면이 있다는 것을 알 수 있습니다. 그 논리로 왜 static_cast는 가상 상속에서 다운 캐스팅을 할 수 없습니까? –