Деструктор (компьютерное программирование)
В объектно-ориентированном программировании ( деструктор иногда сокращенно dtor [1] ) — это метод который вызывается механически непосредственно перед памяти объекта . , освобождением [2] Это может произойти, когда его время жизни привязано к области и выполнение выходит из области, когда оно встроено в другой объект, время жизни которого заканчивается, или когда оно было выделено динамически и освобождено явно. Его основная цель — освободить ресурсы (выделение памяти, открытые файлы или сокеты, соединения с базой данных , блокировки ресурсов и т. д.), которые были получены объектом в течение его жизни, и/или отменить регистрацию у других объектов, которые могут хранить ссылки на него. Использование деструкторов необходимо для процесса инициализации сбора ресурсов (RAII).
В большинстве алгоритмов автоматической сборки мусора освобождение памяти может произойти спустя долгое время после того, как объект станет недоступным, что делает деструкторы (в данном случае называемые финализаторами ) непригодными для большинства целей. В таких языках высвобождение ресурсов осуществляется либо с помощью лексической конструкции (например, try..finally, «with» в Python или «try-with-resources» в Java), что эквивалентно RAII, либо явным вызовом функция (эквивалент явного удаления); в частности, многие объектно-ориентированные языки используют шаблон Dispose .
Синтаксис деструктора
[ редактировать ]- C++ : деструкторы имеют то же имя, что и класс, с которым они связаны, но с префиксом тильды (~). [2]
- D : деструкторы объявляются с именем
~this()
(тогда как конструкторы объявляются с помощьюthis()
). - Object Pascal : деструкторы имеют ключевое слово
destructor
и могут иметь определяемые пользователем имена, но в основном называютсяDestroy
. - Objective-C : метод деструктора имеет имя
dealloc
. - Perl : метод деструктора имеет имя
DESTROY
; в расширении объектной системы Moose оно называетсяDEMOLISH
. - PHP : В PHP 5+ метод деструктора имеет имя
__destruct
. В предыдущих версиях PHP не было деструкторов. [3] - Питон : есть
__del__
методы, называемые деструкторами в руководстве по языку Python 2, [4] но на самом деле они являются финализаторами , как это признано в Python 3. [5] - Rust : метод деструктора ржавчины имеет название
drop
. [6] - Swift : метод деструктора имеет имя
deinit
.
На С++
[ редактировать ]Деструктор имеет то же имя, что и класс, но перед ним стоит тильда (~). [2] Например, класс foo будет иметь деструктор ~foo()
. Кроме того, деструкторы не имеют ни параметров, ни возвращаемых типов. [2] Как указано выше, деструктор объекта вызывается всякий раз, когда заканчивается время жизни объекта. [2] Если объект был создан как автоматическая переменная , его время жизни заканчивается и деструктор вызывается автоматически, когда объект выходит за пределы области видимости. Поскольку в C++ нет сборки мусора, если объект был создан с помощью new
(динамически в куче ), то его деструктор вызывается, когда delete
Оператор применяется к указателю на объект. Обычно эта операция происходит внутри другого деструктора, обычно деструктора объекта интеллектуального указателя .
В иерархиях наследования объявление виртуального деструктора в базовом классе гарантирует, что деструкторы производных классов будут вызываться правильно, когда объект удаляется через указатель на базовый класс. Объекты, которые могут быть удалены таким образом, должны наследовать виртуальный деструктор.
Деструктор никогда не должен генерировать исключение. [7]
Неклассовые скалярные типы имеют то, что называется псевдодеструктор, доступ к которому можно получить с помощью typedef
или аргументы шаблона. Эта конструкция позволяет писать код, не зная, существует ли деструктор для данного типа.
int f() {
int a = 123;
using T = int;
a.~T();
return a; // undefined behavior
}
В более старых версиях стандарта псевдодеструкторы не имели никакого эффекта, однако это было изменено в отчете о дефекте, чтобы заставить их завершить время существования объекта, к которому они вызваны. [8]
Пример
[ редактировать ]#include <cstring>
#include <iostream>
class Foo {
public:
Foo(): data_(new char[sizeof("Hello, World!")]) {
std::strcpy(data_, "Hello, World!");
}
Foo(const Foo& other) = delete; // disable copy construction
Foo& operator=(const Foo& other) = delete; // disable assignment
~Foo(void) { delete[] data_; }
private:
friend std::ostream& operator<<(std::ostream& os, const Foo& foo) {
os << foo.data_;
return os;
}
char* data_;
};
int main() {
Foo foo;
std::cout << foo << std::endl;
}
Объекты, которые не могут быть безопасно скопированы и/или назначены, должны быть отключены от такой семантики, объявив их соответствующие функции удаленными на общедоступном уровне инкапсуляции. Подробное описание этого метода можно найти в Скотта Мейерса популярной книге « Эффективный современный C++» (пункт 11: «Предпочитайте удаленные функции частным неопределенным». [9] ).

В C с расширениями GCC
[ редактировать ]коллекции компиляторов GNU из Компилятор C поставляется с двумя расширениями, которые позволяют реализовывать деструкторы:
- The
destructor
атрибут функции [10] позволяет определять функции деструктора с глобальным приоритетом: когдаmain()
возвращает, эти функции вызываются в порядке приоритета перед завершением процесса. См. также: Взлом искусства эксплуатации . [11] - Атрибут очистки переменной позволяет прикрепить к переменной функцию деструктора: функция вызывается, когда переменная выходит за пределы области видимости.
Хохо
[ редактировать ]Деструкторы в Xojo (REALbasic) могут иметь одну из двух форм. В каждой форме используется обычное объявление метода со специальным именем (без параметров и возвращаемого значения). В более старой форме используется то же имя, что и у класса, с префиксом ~ (тильда). В новой форме используется имя Destructor
. Более новая форма предпочтительнее, поскольку она упрощает рефакторинг класса.
Class Foobar // Old form Sub ~Foobar() End Sub // New form Sub Destructor() End Sub End Class
См. также
[ редактировать ]- Финализатор
- Конструктор (информатика)
- Время жизни объекта
- Получение ресурсов — это инициализация
- Правило трех (программирование на C++)
Ссылки
[ редактировать ]- ^ "дтор" . TheFreeDictionary.com . Проверено 14 октября 2018 г.
- ^ Jump up to: а б с д и Себеста, Роберт В. (2012). " "11.4.2.3 Конструкторы и деструкторы" ". Концепции языков программирования (печать) (10-е изд.). Бостон, Массачусетс, США: Аддисон-Уэсли. п. 487. ИСБН 978-0-13-139531-2 .
- ^ Конструкторы и деструкторы , из онлайн-документации PHP.
- ^ «3. Модель данных — документация Python 2.7.18» .
- ^ «3. Модель данных — документация Python 3.10.4» .
- ^ «Деструкторы — Справочник по Rust» .
- ^ GotW # 47: Неперехваченные исключения , по состоянию на 31 июля 2011 г.
- ^ Смит, Ричард; Вотилайнен, Вилле. «P0593R6: Неявное создание объектов для низкоуровневого манипулирования объектами» . open-std.org . Проверено 25 ноября 2022 г.
- ^ Скотт Мейерс: Эффективный современный C++ , О'РЕЙЛИ, ISBN 9781491903995
- ^ Атрибут функции C "деструктор"
- ^ Эриксон, Джон (2008). Взлом искусства эксплуатации . Пресс без крахмала . ISBN 978-1-59327-144-2 .