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

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

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 деструкторов не было.Деструкторы , в онлайн документации по PHP Python: есть методы с именем __del__, называемые деструкторами в руководстве по языку Python 2, но на самом деле они являются финализаторами, как это объявлено в Python 3. Swift: деструкторы имеют имя deinit.

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

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

TClassWithDestructor = class destructor Destroy; override; end;

В Delphi все классы являются потомками, по крайней мере, класса TObject, поэтому, для корректного освобождения памяти, необходимо перекрывать деструктор, используя директиву 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.

Деструктор в Python В Python поддерживаются деструкторы и для них есть ключевое слово del, но, в отличие от delete в C++, del только уменьшает счетчик ссылок на объект и не обязательно немедленно уничтожает объект.

class Destructible: def __init__(self, name: str) -> None: self.name: str = name print(f"Created Destructible: {self.name}")

def __del__(self) -> None: print(f"Destructor called for: {self.name}")

if __name__ == "__main__": d: Destructible = Destructible("My name") print(f"Using Destructible: {d.name}") del d

Подобно Java и C#, в Python есть блок try-with-resources, называемый блоком with или «контекстным менеджером». Он используется для таких вещей, как файлы и сетевые соединения.

from typing import Optional

class Destructible: def __init__(self, name: str) -> None: self.name: str = name

def __enter__(self) -> "Destructible": print(f"Entering context (allocating resource: {self.name})") return self

def __exit__(self, exc_type: Optional[type], exc_val: Optional[Exception], exc_tb: Optional[type]) -> None: print(f"Exiting context (cleaning up resource: {self.name})")

if __name__ == "__main__": with Destructible("Resource A") as d: print(f"Using resource {d.name} inside context")

# Most Python standard library resources support with blocks: with open(file_path, "r") as file: print("Reading the file content:") content: str = file.read() print(content)

Деструктор в 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; } ~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; } ~Son() { delete[] buffer; }

вызов delete object; приведет к последовательному вызову деструкторов ~Son и ~Father.

Ссылки

См. также Класс (программирование) Конструктор Финализатор Блок инициализации

Категория:Метод (информатика) Категория:Статьи с примерами кода на Паскале Категория:Статьи с примерами кода C++