Estoy de acuerdo con la respuesta de @ j6t, pero aquí hay un razonamiento ampliado con referencias estándar.
El comportamiento especial de los dynamic_cast
objetos en construcción y destrucción se describe en [class.cdtor] / 5 del estándar C ++ 17 (borrador final) y de manera equivalente en las versiones estándar anteriores.
En particular dice:
Cuando dynamic_cast
se utiliza [...] en un destructor, [...], si el operando del se dynamic_cast
refiere al objeto en construcción o destrucción, este objeto se considera el más derivado que tiene el tipo de [ ...] clase de destructor. Si el operando del se dynamic_cast
refiere al objeto bajo [...] destrucción y el tipo estático del operando no es un puntero u objeto de la propia clase [...] del destructor o una de sus bases, el resultado de dynamic_cast comportamiento indefinido
El comportamiento indefinido no se aplica aquí, ya que el operando es la expresión this
, que trivialmente tiene el tipo de un puntero a la propia clase del destructor, ya que aparece en el destructor mismo.
Sin embargo, la primera oración establece que dynamic_cast
se comportará como si *this
fuera un objeto de tipo más derivado Base2
y, por lo tanto, la conversión a Base1
nunca puede tener éxito, ya Base2
que no se deriva de Base1
, y dynamic_cast<Base1*>(this)
siempre devolverá un puntero nulo, resultando en el comportamiento que está viendo.
cppreference.com afirma que el comportamiento indefinido ocurre si el tipo de destino del molde no es el tipo de la clase del destructor o una de sus bases, en lugar de que esto se aplique al tipo de operandos. Creo que eso es solo un error. Probablemente, la mención de " nuevo tipo " en el punto 6 se suponía que debía decir " expresión ", lo que haría que coincidiera con mi interpretación anterior.