Деструктор

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Дестру́ктор — специальный метод класса, служащий для деинициализации объекта (например освобождения памяти).

Деструктор в 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.

Виртуальный деструктор[править | править исходный текст]

Деструктор интерфейсов или абстрактных классов обычно делают виртуальным. Такой прием позволяет корректно удалять без утечек памяти, имея лишь указатель на базовый класс[1].

Пусть (на 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.


Ссылки[править | править исходный текст]

  1. Сергей Оленда́ренко. Виртуальные функции и деструктор.

См. также[править | править исходный текст]