Деструктор
Дестру́ктор — специальный метод класса, служащий для деинициализации объекта (например освобождения памяти).
Содержание |
[править] Деструктор в Delphi
Для объявления деструктора в Delphi используется ключевое слово destructor. Имя деструктора может быть любым, но рекомендуется всегда называть деструктор Destroy.
TClassWithDestructor = class destructor Destroy; override; end;
В Delphi все классы являются потомками, по крайней мере, класса TObject, поэтому, для корректного освобождения памяти, необходимо перекрывать деструктор, используя директиву override.
В Delphi прямой вызов деструктора используется редко. Вместо него используют метод Free.
MyObject.Free;
Метод Free вначале проверяет существует ли уничтожаемый объект, а затем вызывает деструктор. Этот прием позволяет избегать ошибок, возникающих при обращении к несуществующему объекту.
[править] Деструктор в С++
#include <iostream>
using namespace std;
class NameOfClass
{
private:
int a;
public:
NameOfClass(int m);
~NameOfClass();
};
NameOfClass::~NameOfClass()
{
cout << this->a << endl;
}
NameOfClass::NameOfClass(int m)
{
a = m;
}
~NameOfClass() — деструктор, имеет имя ~NameOfClass, не имеет входных параметров.
В данном случае при уничтожении объекта выводит в консоль параметр a.
[править] Виртуальный деструктор
Практически всегда деструктор делается виртуальным. Делается это для того, чтобы корректно (без утечек памяти) уничтожались объекты не только заданного класса, а и любого производного от него. Например: в игре уровни, звуки и спрайты могут создаваться загрузчиком, а уничтожаться — менеджером памяти, для которого нет разницы между уровнем и спрайтом.
Пусть (на C++) есть тип Father и порождённый от него тип Son:
class Father { public: Father() {} ~Father() {} }; class Son : public Father { public: int* buffer; Son() : Father() { buffer = new int[1024]; } ~Son() { delete[] buffer; } };
Нижеприведённый код является некорректным и приводит к утечке памяти.
Father* object = new Son(); // вызывается Son() delete object; // вызывается ~Father()!!
Однако, если сделать деструктор Father виртуальным:
class Father { public: Father() {} virtual ~Father() {} }; class Son : public Father { private: int* buffer; public: Son() : Father() { buffer = new int[1024]; } ~Son() { delete[] buffer; } };
вызов delete object; приведет в последовательному вызову деструкторов ~Son и ~Father.
В Delphi все классы порождаются от TObject, деструктор которого является виртуальным, поэтому нет необходимости самому объявлять деструкторы любых объектов виртуальными.