Деструктор является дополнением конструктора. Он имеет то же имя, что и класс, но с префиксом-тильдой ~. Он вызывается всякий раз, когда уничтожается представитель класса. Для деструктора существуют следующие правила:
• деструктор не может иметь аргументов;
• деструктор не может возвращать значение;
• деструктор не наследуется;
• деструктор не может быть объявлен как const, volatile или static;
• деструктор может быть объявлен как virtual.
Компилятор генерирует конструктор по умолчанию, если вы его не определите явно. Наиболее распространенное применение деструкторов - освобождение памяти, выделенной конструктором при создании объекта. Например:
#include <iostream>
#include <cstring>
using namespace std;
class Buffer
{
private:
char *buf; //указатель на строку
public:
Buffer(char *s)
{
//вычисляем длину строки
int length = strlen(s);
//выделяем необходимую память
buf = new char[length+1];
strcpy(buf, s); //копируем строку в буфер
}
~Buffer() //деструктор
{
cout << “Удаляем буфер.\n”;
if (buf) delete []buf; //освобождаем память
}
void View() //отобразим строку на дисплее
{
//endl – “end line” – перевод строки
cout << buf << endl;
}
};
int main ()
{
Buffer cBuf = “Пример.”;
cout << cBuf;
cBuf.View();
return 0;
}
В результате работы программы на дисплей будет выведено:
Пример.
Удаляем буфер.
При завершении работы программы будет автоматически вызван деструктор класса ~Buffer, что гарантирует освобождение памяти, выделенной для объекта класса Buffer. То есть память будет возвращена системе при уничтожении объекта, а не останется неопределенной.
При уничтожении объекта деструктор будет вызван автоматически. Существует очень мало ситуаций, когда необходимо явно вызывать деструктор, например при помещении объекта в область, которая (непосредственно) не управляется стандартным распределением свободной памяти. В этом случае деструктор вызывается явно. Для предыдущего примера:
cBuf.~Buffer();
Если был объявлен указатель pBuf на класс Buffer, то вызов деструктора выглядел бы как:
cBuf->~Buffer();
|