В общем случае это (очень заслуженное) Undefined Behavior для преобразования вниз от (динамического) 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 ?
Здесь мы легко можем представить, что компилятор делает правильные вещи. Но со стандартной точки зрения он все еще не определен?
Изменить: static_cast - это случайный выбор для иллюстрации, он также интересен при работе с другими приведениями!
obj
неDerivedForInt
. - person Simple   schedule 28.11.2013