stringtranslate.com

Деструктор (компьютерное программирование)

В объектно-ориентированном программировании деструктор ( иногда сокращенно dtor [1] ) — это метод , который вызывается механически непосредственно перед освобождением памяти объекта . [2] Это может произойти, когда его время жизни привязано к области и выполнение выходит из области, когда оно встроено в другой объект, время жизни которого заканчивается, или когда оно было выделено динамически и освобождено явно. Его основная цель — освободить ресурсы (выделение памяти, открытые файлы или сокеты, соединения с базой данных , блокировки ресурсов и т. д.), которые были получены объектом в течение его жизни, и/или отменить регистрацию у других объектов, которые могут хранить ссылки на него. Использование деструкторов необходимо для процесса инициализации сбора ресурсов (RAII).

В большинстве типов алгоритмов автоматической сборки мусора освобождение памяти может произойти спустя долгое время после того, как объект станет недоступным, что делает деструкторы (в данном случае называемые финализаторами ) непригодными для большинства целей. В таких языках высвобождение ресурсов осуществляется либо с помощью лексической конструкции (например, try..finally, «with» в Python или «try-with-resources» в Java), что эквивалентно RAII, либо явным вызовом функция (эквивалент явного удаления); в частности, многие объектно-ориентированные языки используют шаблон Dispose .

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

На С++

Деструктор имеет то же имя, что и класс, но перед ним стоит тильда ( ~). [2] Например, класс с именем foo будет иметь деструктор . Кроме того, деструкторы не имеют ни параметров, ни возвращаемых типов. [2] Как указано выше, деструктор объекта вызывается всякий раз, когда заканчивается срок службы объекта. [2] Если объект был создан как автоматическая переменная , его время жизни заканчивается, и деструктор вызывается автоматически, когда объект выходит за пределы области видимости. Поскольку в C++ нет сборки мусора, если объект был создан с помощью инструкции (динамически в куче ), то его деструктор вызывается, когда оператор применяется к указателю на объект. Обычно эта операция происходит внутри другого деструктора, обычно деструктора объекта интеллектуального указателя .~foo()newdelete

В иерархиях наследования объявление виртуального деструктора в базовом классе гарантирует, что деструкторы производных классов будут вызываться правильно, когда объект удаляется через указатель на базовый класс. Объекты, которые могут быть удалены таким образом, должны наследовать виртуальный деструктор.

Деструктор никогда не должен генерировать исключение. [7]

Неклассовые скалярные типы имеют то, что называетсяпсевдодеструктор , доступ к которому можно получить с помощьюtypedefаргументов шаблона. Эта конструкция позволяет писать код, не зная, существует ли деструктор для данного типа.

int f () { int a = 123 ; используя Т = int ; а . ~ Т (); вернуть ;// неопределенное поведение }              

В более старых версиях стандарта псевдодеструкторы не имели никакого эффекта, однако это было изменено в отчете о дефекте, чтобы заставить их завершить время существования объекта, к которому они вызваны. [8]

Пример

#include <cstring> #include <iostream>  class Foo { public : Foo () : data_ ( new char [ sizeof ( "Hello, World!" )]) { std :: strcpy ( data_ , "Hello, World!" ); }          Foo ( const Foo & другое ) = удалить ; // отключаем построение копирования Foo & operator = ( const Foo & other ) = delete ; // отключаем присвоение             ~ Foo ( void ) { delete [] data_ ; }    частный : друг std :: ostream & оператор << ( std :: ostream & os , const Foo & foo ) { os << foo . данные_ ; вернуть ОС ; }               символ * данные_ ; }; int main () { Foo foo ; std :: cout << foo << std :: endl ; }         

Объекты, которые не могут быть безопасно скопированы и/или назначены, должны быть отключены от такой семантики, объявив их соответствующие функции удаленными на общедоступном уровне инкапсуляции. Подробное описание этого метода можно найти в популярной книге Скотта Мейерса « Эффективный современный C++» (пункт 11: «Предпочитайте удаленные функции частным неопределенным». [9] ).

Класс UML в C#, содержащий конструктор и деструктор.

В C с расширениями GCC

Компилятор C из коллекции компиляторов GNU поставляется с двумя расширениями, позволяющими реализовывать деструкторы:

Содзё

Деструкторы в Xojo (REALbasic) могут иметь одну из двух форм. В каждой форме используется обычное объявление метода со специальным именем (без параметров и возвращаемого значения). В более старой форме используется то же имя, что и у класса, с префиксом ~ (тильда). В новой форме используется имя Destructor. Более новая форма предпочтительнее, поскольку она упрощает рефакторинг класса.

Класс Фубар // Старая форма Подписка ~Foobar() Конец субтитра // Новая форма Поддеструктор() Конец субтитраКонечный класс

Смотрите также

Рекомендации

  1. Ссылки TheFreeDictionary.com . Проверено 14 октября 2018 г.
  2. ^ abcde Sebesta, Роберт В. (2012). "«11.4.2.3 Конструкторы и деструкторы»". Концепции языков программирования (печать) (10-е изд.). Бостон, Массачусетс, США: Аддисон-Уэсли. стр. 487. ISBN. 978-0-13-139531-2.
  3. ^ Конструкторы и деструкторы из онлайн-документации PHP.
  4. ^ «3. Модель данных — документация Python 2.7.18» .
  5. ^ «3. Модель данных — документация Python 3.10.4» .
  6. ^ "Деструкторы - Справочник по Rust" .
  7. ^ GotW # 47: Неперехваченные исключения, по состоянию на 31 июля 2011 г.
  8. ^ Смит, Ричард; Вотилайнен, Вилле. «P0593R6: Неявное создание объектов для низкоуровневого манипулирования объектами». open-std.org . Проверено 25 ноября 2022 г.
  9. ^ Скотт Мейерс: Эффективный современный C++ , О'РЕЙЛИ, ISBN 9781491903995 
  10. ^ Атрибут функции C "деструктор"
  11. ^ Эриксон, Джон (2008). Взлом искусства эксплуатации . Пресс без крахмала . ISBN 978-1-59327-144-2.