У меня 3 класса
class A
{
A();
virtual ~A();
}
class B : public A
{
B();
~B();
}
class C
{
void *obj;
C() : obj(nullptr) {}
~C() { if (obj) delete obj; }
}
когда я использую класс C
как контейнер для любого потомка класса A
и попробуй удалить C
пример. A
, B
не разрушен деструктор это нормально? Что такое решение?
C* instance = new C();
instance.obj = new B();
//Magic
delete instance; // A and B destructor is not called
Удаление указателя на несовместимый тип (в том числе void
) дает неопределенное поведение.
Каково решение?
new
или базовый класс, если у него есть виртуальный деструктор; или жеstd::shared_ptr<void>
инициализировано из std::shared_ptr<correct_type>
: его удалитель сделает правильную вещь.В этом случае, похоже, вы можете просто хранить A*
скорее, чем void*
, так как вы говорите, что это должен быть «контейнер для любого потомка класса A
».
Кстати, нет необходимости проверять, является ли указатель нулевым, перед его удалением.
Вы удаляете void*
, так delete
не знает, что это B*
поэтому деструктор не может быть вызван. Вы должны использовать указатель класса, если хотите, чтобы деструктор вызывался при удалении.
Например, это все классы, которые могут быть C obj
расширить А, затем использовать A*
,
Да, удалять нужен конкретный тип.