Деструктор не вызывается при удалении пустого указателя

У меня 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

2

Решение

Удаление указателя на несовместимый тип (в том числе void) дает неопределенное поведение.

Каково решение?

  • используйте правильный тип: либо тип, который вы указали newили базовый класс, если у него есть виртуальный деструктор; или же
  • использование std::shared_ptr<void>инициализировано из std::shared_ptr<correct_type>: его удалитель сделает правильную вещь.

В этом случае, похоже, вы можете просто хранить A* скорее, чем void*, так как вы говорите, что это должен быть «контейнер для любого потомка класса A».

Кстати, нет необходимости проверять, является ли указатель нулевым, перед его удалением.

12

Другие решения

Вы удаляете void*, так delete не знает, что это B* поэтому деструктор не может быть вызван. Вы должны использовать указатель класса, если хотите, чтобы деструктор вызывался при удалении.

Например, это все классы, которые могут быть C obj расширить А, затем использовать A*,

6

Да, удалять нужен конкретный тип.

0
По вопросам рекламы [email protected]