Сегодня столкнулся с тем, что для моего проекта на плюсах просто необходимо преобразование типов как вверх, так и вниз (большая часть объектов хранится в одном stl контейнере, хранящем указатели имеющие тип интерфейса, от которого наследуется добрая половина всего, без кастования типов пришлось бы переносить некоторый функционал в сам интерфейс, а это еще больший говнокод)
Допустим, у нас есть такой код.
// Предположим,что класс Foo абстрактный
// (иначе downcast попросту невозможен)
class Foo {
// какая-то переменная
SomeType something;
// что-то еще
public:
// меняем вышеназванную переменную
virtual void setSomething(SomeType newSomething);
// что-то еще
};
class Bar : public Foo{
// что-то
public:
void setSomething(SomeType newSomething) override;
// получаем значение
SomeType getSomething();
};
int main(){
// создаем указатель, выделяем память и задаем параметр
Bar * somepointer_a = new bar;
somepointer_a->setSomething(SomeType alpha);
//Создаем новый указатель с типом родительского класса через \
//кастование типов
Foo * somepointer_b = dynamic_cast<Foo*>(someponter_a);
//Используем функцию, которая была оверрайднута
somepointer_b->setSomething(SomeType beta);
//Создаем указатель изначального типа и получаем значение
Bar * somepointer_c = dynamic_cast<Bar*>(someponter_b);
std::cout << somepointer_c->getSomething();
}
Есть ли вероятность, что на stdout выведет не то, что было в beta, а то что было в alpha или вообще вылетит с ошибкой? А если еще конктретнее, можно ли это считать неопределенным поведением и способна ли последовательность из upcast и downcast привести к потере данных?