Я согласен с ответом @ j6t, но вот расширенные рассуждения со стандартными ссылками.
Особое поведение dynamic_cast
для строящихся и разрушаемых объектов описывается [class.cdtor] / 5 стандарта C ++ 17 (окончательный вариант) и аналогично предыдущим версиям стандарта.
В частности, в нем говорится:
Когда используется dynamic_cast
[...] в деструкторе, [...], если операнд dynamic_cast
относится к строящемуся или разрушаемому объекту, этот объект считается наиболее производным объектом, который имеет тип [. ..] класс деструктора. Если операнд dynamic_cast
относится к объекту, который [...] уничтожается, и тип операнда stati c не является указателем или объектом собственного класса деструктора [...] или одного из его Основы, dynamic_cast приводит к неопределенному поведению.
Неопределенное поведение здесь не применимо, так как операндом является выражение this
, которое тривиально имеет тип указателя на собственный класс деструктора, так как оно появляется в самом деструкторе.
Однако в первом предложении говорится, что dynamic_cast
будет вести себя так, как если бы *this
был наиболее производным объектом типа Base2
, и поэтому приведение к Base1
может никогда не удастся, потому что Base2
не является производным от Base1
, а dynamic_cast<Base1*>(this)
всегда будет возвращать нулевой указатель, что приведет к поведению, которое вы видите.
cppreference.com заявляет, что неопределенное поведение происходит, если тип назначения приведения не является типом класса деструктора или одной из его баз, вместо того, чтобы иметь это приложение к типу операндов. Я думаю, что это просто ошибка. Вероятно, упоминание « new-type » в пуле 6 должно было сказать « выражение », что соответствовало бы моей интерпретации выше.