więc niemożliwe jest przygnębiony użyciu static_cast
z wirtualnego dziedziczenia, ale jak to jest możliwe, aby wykonać następujące czynności uskok:W jaki sposób można użyć static_cast w przypadku dziedziczenia wirtualnego?
class Base {...};
class Derived : public virtual Base {...};
...
Derived *d = new Derived();
Base *b = static_cast<Base*>(d);
układ pamięci obiektu:
[ derived part | base part ]
wiem, że upcasting jest uważany "bezpieczny", ale w jaki sposób kompilator może znać przesunięcie do bazowego pod-obiektu podczas kompilacji, kiedy dziedziczenie jest wirtualne? Czy static_cast
używają vtable
?
Jest to szczególnie kłopotliwe, kiedy mamy coś takiego (zauważ, że to nie jest wirtualny):
class Third : public Derived {...};
...
Derived *d = new Third(); // non-virtual upcast, no offset will be added
Base *b = static_cast<Base*>(d);
Tym razem użył tego samego static_cast
linię, ale przesunięcie do sub-object Base
jest inna!
układ pamięci obiektu:
[ derived part | third part | base part ]
Więc jak można określić w czasie kompilacji, czy to zależy od rzeczywistego dynamicznego typu obiektu d
punkty?
Zwykle tak jest z tego, co wiem, że przesunięcia są przechowywane w vtable. Jednak to nie odpowiada na pytanie, jak to zrobić statycznie podczas kompilacji. Jeśli przyjrzeć się dwóm dostarczonym przeze mnie przypadkom, pojawia się pytanie, który z nich ma odpowiednie przesunięcie? Którym powinien się przyglądać kompilator, vable programu Derived lub vtable Third? Oczywiście 2 przesunięcia w vtables są różne, a wybór odpowiedniego vtable zależy od typu run-s. Dlatego nie mogę zrozumieć, jak to jest zrobione statycznie. –
"Statyczny" w 'static_cast' nie oznacza, że jest on wykonywany podczas kompilacji! Oznacza to po prostu, że kompilator może statycznie ustalić, gdzie znaleźć informacje w czasie kompilacji: Na przykład, wie gdzie szukać offsetu w vtable lub gdzie znajduje się wbudowany wskaźnik do bazy (w zależności od tego, jak wirtualne dziedziczenie jest zaimplementowane). Nie będzie szukał dopasowania jakiejś klasy w vtable, jak robi to 'dynamic_cast'. –
Mówisz, że static_cast ma jakiś aspekt dynamiczny, widzę. Według tej logiki, dlaczego static_cast nie może powodować downcastingu w dziedziczeniu wirtualnym? –