Давайте рассмотрим следующий код:
#include <iostream>
struct A{ virtual void foo(){ } };
struct B : A { virtual void foo(){ } };
A *a = new B;int main()
{
delete a; //UB?
}
Я сознательно не определил виртуальный деструктор. Компилятор напечатал сообщение о возникновении UB, это правда?
Формально у вас есть UB, если вы удаляете через указатель на T, который не является наиболее производным типом, и у T нет виртуального деструктора.
На практике вы можете избежать неприятностей с этим, если у вас нет данных, но это все еще очень плохая и ненужная практика.
Примечание: когда вы используете shared_ptr
он создает функцию удаления в точке инициализации, и эта функция удаления может запомнить исходный тип, который, если этот тип является наиболее производным типом, обеспечивает четко определенное удаление. Например. в твоем случае shared_ptr<A> p( new B );
было бы хорошо.