Interested Article - Деструктор

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

Синтаксис деструктора

  • C++ : имя деструктора совпадает с именем класса, перед которым стоит символ тильда (~). См. .
  • D : деструкторы имеют имя ~this() .
  • Rust : деструкторы построены на типаже Drop .
  • Delphi : деструкторы имеют ключевое слово destructor и могут иметь любое имя, но обычно именуется как Destroy .
  • Object Pascal : деструкторы имеют ключевое слово destructor и могут иметь любое имя, но обычно именуется как Destroy .
  • Objective-C : деструкторы имеют имя dealloc .
  • Perl : деструкторы имеют имя DESTROY ; в расширении Moose для Perl 5, деструкторы имеют название DEMOLISH .
  • PHP : В PHP 5+, деструкторы имеют имя __destruct . В более ранних версиях PHP деструкторов не было.
  • Python : есть методы с именем __del__ , называемые деструкторами в руководстве по языку Python 2, но на самом деле они являются Финализаторами , как это объявлено в Python 3.
  • Swift : деструкторы имеют имя deinit .

Деструктор в Delphi

Для объявления деструктора в Delphi используется ключевое слово destructor . Имя деструктора может быть любым, но рекомендуется всегда называть деструктор Destroy .

  TClassWithDestructor = class
    destructor Destroy; override;
  end;

В Delphi все классы являются потомками, по крайней мере, класса , поэтому, для корректного освобождения памяти, необходимо перекрывать деструктор, используя директиву override .

В Delphi прямой вызов деструктора используется редко. Вместо него используют метод Free .

 MyObject.Free;

Метод Free вначале проверяет существует ли уничтожаемый объект, а затем вызывает деструктор. Этот прием позволяет избегать ошибок, возникающих при обращении к несуществующему объекту.

Деструктор в C++

    #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 .

Деструктор в Rust

struct Foo {
    i: i32,
}

impl Foo {
    fn new(i: i32) -> Foo {
        Foo { i }
    }
}

impl Drop for Foo {
    fn drop(&mut self) {
        println!("{}", self.i);
    }
}

В блоке impl для структуры Foo реализуется одноимённый метод типажа Drop . В коде ниже создаётся переменная foo . Благодаря умной модели памяти, деструктор будет вызван автоматически и без накладных расходов, как только закончится область видимости переменной.

let foo = Foo::new(42);

Виртуальный деструктор

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

Пусть (на 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. от 30 августа 2019 на Wayback Machine , в онлайн документации по PHP
  2. . Дата обращения: 31 августа 2019. 19 сентября 2019 года.
  3. . Дата обращения: 31 августа 2019. 26 октября 2012 года.
  4. . doc.rust-lang.org. Дата обращения: 31 октября 2019. 29 сентября 2019 года.
  5. Сергей Оленда́ренко. . Дата обращения: 1 июля 2013. 2 августа 2013 года.

См. также

Источник —

Same as Деструктор