Когда мне нужно объявить свой собственный деструктор?

class Point    
{
public:
    float x,y;
    Point() {}
    Point(float,float);
    Point operator + (Point);
    Point operator * (double);
    void rotate_p(float);
    void render_p(Point*);
    void sub(float);
    float get_dist();//get_distance
};

Как вы можете видеть, у этого класса нет указателей как нестатических данных-членов, поэтому я думаю, что могу просто использовать деструктор по умолчанию; это точно?


Вопрос

  • Когда мне нужно объявить свой собственный деструктор?

Ответ 1

Введение

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


Когда обычно мне нужно объявить свой собственный деструктор?

Обычно вам нужно явно объявить свой собственный деструктор, если:

  • Вы объявляете класс, который должен служить базой для наследования, включая полиморфизм, если вам это нужно, вам понадобится виртуальный деструктор, чтобы убедиться, что деструктор класса Derived призван уничтожить его указатель/ссылка на базу.

  • Вам нужно освободить ресурсы, приобретенные классом во время его отпускания

    • Пример 1: класс имеет дескриптор файла, его нужно закрыть, когда объект разрушается; деструктор - идеальное место.

    • Exempel 2: класс принадлежит объекту с продолжительностью динамического хранения, так как срок жизни объекта может потенциально прожить долго после уничтожения экземпляра класса, вам нужно будет явно уничтожить его в деструкторе.


Неявно сгенерированный деструктор

Если вы явно не объявите свой собственный деструктор, для вас будет создан неявно сгенерированный деструктор.

14.4p4 Деструкторы [class.dtor]

Если класс не имеет объявленного пользователем деструктора, деструктор   неявно объявляет как дефолт (8.4). Неявно объявлено   destructor является встроенным публичным элементом своего класса.

src: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf


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

14.4p5 Деструкторы [class.dtor]

Деструктор по умолчанию для класса X определяется как delete, если:

     
  •   
  • X является объединенным классом, который имеет вариантный член с нетривиальным   деструктор,

      
  • любой из нестатических членов данных имеет тип класса M (или массив   ), а M имеет удаленный деструктор или деструктор, который является   недоступный от деструктора по умолчанию,

      
  • любой прямой или виртуальный базовый класс имеет удаленный деструктор или   деструктор, недоступный от деструктора по умолчанию,

      
  • или, для виртуального деструктора, поиск не-массива освобождения   функция приводит к двусмысленности или в функции, которая удалена   или недоступен для деструктора по умолчанию.

      

src: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf


Подробнее можно прочитать по следующей ссылке:

Ответ 2

Основная цель Destructor - освободить используемую память из кучи или удалить ссылки на другие объекты и т.д. Здесь вы не выделяете память из кучи, вы не создаете никаких отношений между объектами, поэтому деструктор не нужен.

Ответ 3

Когда память учитывается во время компиляции (т.е. память не выделяется во время выполнения), тогда может быть создан деструктор, но это необязательно. В таких случаях деструктор для класса подразумевается определением класса; деструктор будет предоставлен вам за кулисами, и память будет освобождена, когда экземпляры класса выйдут из области видимости.

EDIT: здесь можно найти простой, удобный учебник - http://www.learncpp.com/cpp-tutorial/86-destructors/

Ответ 4

  • Хотя, если вы его не определяете, язык определит деструктор для вас.

  • Как правило, рекомендуется определить деструктор как virtual, чтобы гарантировать, что все будет в порядке, если кто-то наследует ваш класс.

  • Тем не менее, необходимо определить ваш деструктор, если вы выделяете динамическую память в своих конструкторах и убедитесь, что в ней будет удалена любая выделенная память, чтобы избежать утечек памяти.

  • Другое предложение состоит в том, что если ваш компилятор поддерживает функции С++ 11, было бы лучше избегать указателей raw для выделения памяти и использовать интеллектуальные указатели (то есть RAII). Таким образом, вам не придется удалять ранее выделенную память в ваших деструкторах.

Ответ 5

Деструктор - это код, который выполняется, когда объект уничтожается... period.

Что входит в деструктор, зависит от семантики, связанной с объектом.

Типичные вещи, которые входят в деструктор (но могут пойти в другом месте, например, думать о объединенном объекте),

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

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

Компилятор предоставит вам деструктор по умолчанию, если вы его не определите. Кроме того, атрибуты, содержащиеся в классе, получат свой деструктор, вызываемый автоматически после запуска (неявного/явного) класса деструктора класса.

Ответ 6

Вы также можете посмотреть на "Правило трех", Правило трех (также известное как Закон Большой тройки или Большая тройка) является эмпирическим правилом на С++, который утверждает, что если класс определяет одно из следующего, он должен явно явно определить все три:

деструктор, копировать конструктор, оператор присваивания копии, Ссылка Wikipedia: http://en.wikipedia.org/wiki/Rule_of_three_ (C% 2B% 2B_programming)