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

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

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

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

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

В C ++

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

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

Деструктор никогда не должен вызывать исключения.

Пример

#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: «Предпочитайте удаленные функции частным неопределенным»).

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

В GNU Compiler Collection «сек C компилятор поставляется с 2 - расширений , которые позволяют реализовать деструкторов:

  • destructor Атрибут функции позволяет определять глобальные приоритизированные функции деструктора: когда main() возвращается, то эти функции вызываются в порядке приоритета перед процессом завершается. См. Также: Взлом искусства эксплуатации .
  • Очистки атрибут переменной позволяет подключать функцию деструктора к переменной: функция вызывается , когда переменная выходит из области видимости.

Xojo

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

Class Foobar
  // Old form
  Sub ~Foobar()
  End Sub

  // New form
  Sub Destructor()
  End Sub
End Class

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

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