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