Все ответы описывают конкретные случаи, но есть общий ответ:
Вы вызываете dtor явно каждый раз, когда вам нужно просто уничтожить объект (в смысле C ++), не освобождая память, в которой находится объект.
Обычно это происходит во всех ситуациях, когда выделение / освобождение памяти управляется независимо от создания / уничтожения объекта. В этих случаях построение происходит путем размещения new на существующем фрагменте памяти, а разрушение происходит посредством явного вызова dtor.
Вот необработанный пример:
{
char buffer[sizeof(MyClass)];
{
MyClass* p = new(buffer)MyClass;
p->dosomething();
p->~MyClass();
}
{
MyClass* p = new(buffer)MyClass;
p->dosomething();
p->~MyClass();
}
}
Другой примечательный пример - это значение по умолчанию, std::allocator
когда std::vector
элементы создаются в vector
процессе push_back
, но память распределяется по частям, поэтому она предшествует конструкции элемента. И, следовательно, vector::erase
должен уничтожить элементы, но не обязательно освобождает память (особенно если скоро должен произойти новый push_back ...).
Это «плохой дизайн» в строгом смысле ООП (вы должны управлять объектами, а не памятью: факт, что объекты требуют памяти, является «инцидентом»), это «хороший дизайн» в «низкоуровневом программировании» или в случаях, когда память не взяты из "бесплатного магазина", в котором operator new
покупаются по умолчанию .
Плохой дизайн, если это происходит случайно вокруг кода, хороший дизайн, если это происходит локально с классами, специально разработанными для этой цели.