В общем случае это (очень хорошо заслуженный) Undefined Поведение для dowcast от (динамического) Base
к одному из классов-получателей Derived
Очевидный UB
class Base
{
public:
virtual void foo()
{ /* does something */ }
int a;
}
class Derived : public Base
{
public:
virtual void foo()
{ /* does something different */ }
double b;
}
Base obj;
Derived derObj = *static_cast<Derived *>(&obj); // <- here come the demons
В текущем подходе к реализации компиляторов здесь, очевидно, будут, по крайней мере, проблемы несогласованных значений в Vtable и b, содержащих значения мусора. Поэтому имеет смысл, что стандарт не определяет поведение нисходящего в этих условиях.
Не столь очевидный наивный случай
Но мне было любопытно узнать , если бы были определенные уступки этому правилу в конкретных случаях? Например:
class Base
{
public:
void foo()
{ /* does something */ }
int a = 1;
double b = 2.;
}
class DerivedForInt : public Base
{
int getVal()
{ return a }
}
Base obj;
DerivedForInt derObj = *static_cast<DerivedForInt *>(&obj); // <- still an UB ?
Здесь мы можем легко представить, что компилятор делает правильные вещи. Но с точки зрения стандартного, все еще Undefined?
Изменить: static_cast - случайный выбор для иллюстрации, также интересно работать с другими приведениями!