Деструктор (destructor, dtor) вызывается при уничтожении объекта класса и выполняет ряд действий по его деинициализации. Обычно это означает освобождение занятых объектом ресурсов, например, динамической памяти, выделенной для поля объекта в его конструкторе.
Деструктор представляет собой функцию без параметров и возвращаемого значения, имя которой выглядит следующим образом: ~имя_класса.
Например, деструктор класса complex:
~complex()
{
cout << "\nУничтожили объект с полями " << real << ' '
<< imaginary << endl;
};
Т.к. complex – простейший класс и он не захватывает никаких ресурсов, его деструктор не выполняет никакой полезной работы, а просто выводит сообщение о своем вызове. В таких случаях в деструкторе обычно нет необходимости, и он не объявляется. Если деструктор класса не объявлен, то, как и в случае с конструктором, компилятор сгенерирует автоматический деструктор с пустым телом.
Деструктор вызывается автоматически каждый раз, когда объект покидает область существования и его необходимо уничтожить. В приведённой программе объекты с1 и c2 будут уничтожены при выходе из функции main, в которой они объявлены. Перед уничтожением будут вызваны их деструкторы.
Деструктор можно вызывать и явно, если возникла необходимость уничтожить объект. Вызывается деструктор аналогично любому другому методу объекта:
с1.~complex();
Следует заметить, что в большинстве случаев явный вызов деструктора не нужен и использовать его не рекомендуется.
Пример класса, использующего динамическое выделение памяти:
class array
{
public:
array(unsigned short n)
{
size = n;
data = new int[size];
memset(data, 0, n*sizeof(int));
}
~array()
{
delete[] data;
}
...
private:
int* data;
unsigned short size;
};
Конструктор класса array выделяет память под динамический массив data, который является закрытым полем класса. Т.к. любая память, которая в программе была динамически выделена, должна быть явно освобождена, то массив data необходимо будет удалить с использованием оператора delete[]. Лучшим местом для этого является деструктор класса, который будет вызван перед уничтожением объекта.
Предостережение! Если память не освободить явно, как это сделано в деструкторе, то при уничтожении объекта удалится указатель data, а память, на которую он ссылался, так и останется занятой. После этого освободить её можно будет только завершив программу.