Мне очень понравилось, как элегантно стандарт описывает преобразования между базовыми и производными типами. По мне, это даже нагляднее, чем в большинстве популярных статей об этом (и тем более непопулярных, которые рассматривают неочевидные моменты очень развёрнуто). Давайте посмотрим на это поближе.
В этой статье я буду пользоваться 20м стандартом. B значит вендетта base, D - derived.
Начнём с каста вверх: 7.3.11 Pointer conversions, пункт 3. Это standard conversion.
The result of the conversion is a pointer to the base class subobject of the derived class object. И никаких картинок не надо - сразу ясно, как будет происходить этот самый slice (он же срез - устоявшееся название для сдвига указателя при касте вверх). Указатель просто сдвигается на базовый подобъект производного класса. А если вариантов несколько, то и указатель некуда двигать.
Каст вниз - самое неочевидное, на мой взгляд. 7.6.1.8 Static cast, пункт 2.
Но стандарт и это объясняет парой фраз. В самом деле, если мы пытаемся сделать целое из части, то результат определён лишь в случае, когда целое уже существует. Почему при этом не удаётся создать D из виртуального B? Потому что B не принадлежит ни одному целому. Даже low-level абстракции не понадобились.
Все эти простые вещи спустя лекции и гугл дошли до меня только через стандарт. Он ответил на много тупых вопросов. Непонятно, почему его не рекомендуют новичкам.
Надеюсь, и вы прониклись лаконичностью оригинала C++. Так или иначе, этот случай мотивировал меня пересмотреть своё отношение к источникам информации. Вэлком в комменты :)
P.S. Изначально я хотела сделать пост, но там можно только 1 картинку. Поэтому стиль и формат получились соответствующие. Нравятся ли вам подобные вольные маленькие статьи?