Подтвердить что ты не робот

Деструкторы в С++

Разве деструктор освобождает память, назначенную объекту, к которому он принадлежит, или он просто вызван так, чтобы он мог выполнить некоторую домашнюю уборку до того, как объект будет освобожден компилятором?

4b9b3361

Ответ 1

"Компилятор" ничего не удаляет. Он создает код, который делает вещи во время выполнения.

Когда вы пишете delete somePointer;, компилятор, по сути, пишет:

  if ( has_virtual_destructor( * somePointer  ) ) {
       // virtual dispatch to a compiler-generated function
      dynamic_cast< true_dynamic_type * >(somePointer)->destroy_dynamic_type();
       /* contents of true_dynamic_type::destroy_dynamic_type() {
              this->~true_dynamic_type();
              operator delete( this); // executed within class context
       } */
  } else {
      somePointer->~ClassName();
      operator delete(somePointer);
  }

Другими словами, деструктор вызывается, а затем оператор delete вызывается для освобождения хранилища.

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

Обратите внимание, что оператор верхнего уровня if на самом деле не является частью сгенерированного кода; компилятор принимает это решение во время компиляции.

Ответ 2

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

ОС будет заниматься деаллоцированием самого объекта после завершения деструктора.

Ответ 3

1) destructor не принадлежит объекту, он принадлежит классу

2) Он вызывает деструктор для всех определяемых пользователем типов (объектов класса) внутри своего класса.

3) Очистка - это необязательная активность, которая выполняется, только если это действительно необходимо

Ответ 4

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

Ответ 5

В частности, никто, кроме программиста, не освобождает память на С++. Если объект находится в стеке, он находится в пространстве памяти программы и занимает пространство в течение всего жизненного цикла программы. Если он находится в куче, тот, кто создал объект, несет ответственность за его освобождение. То, что делает delete. Это приводит нас к деструктору - если вы создаете объекты в своем классе, деструктор позволяет удалить их, поскольку класс оставляет область. Он позволяет вам "выключать свет при выходе".

Ответ 6

Деструкторы автоматически вызывают деструкторы на переменные-члены уничтожаемого объекта. Эти деструкторы могут или не могут освободить память. Однако указатель не имеет деструктора, или, если хотите, деструктор указателя ничего не делает. Он не освобождает память, на которую указывает. Если объект содержит указатель на объект, полученный из "нового" или "malloc", то до программиста этого объекта требуется сделать деструктор правильным. Вы должны запрограммировать свой деструктор на "удаление" или "освобождение" памяти, если она концептуально является частью разрушаемого объекта. Например, "векторный" объект обычно получает память из кучи, поскольку объем требуемой памяти обычно не известен во время компиляции. Эта память концептуально является частью векторного объекта, и, следовательно, программист векторного класса должен называть "удалить" его в деструкторе. Стандартные классы библиотеки шаблонов, такие как std::vector, делают это правильно.

С другой стороны, некоторые объекты содержат ссылки на другие объекты. Словарь или индекс будут содержать ссылки (указатели) на объекты, которые не являются их концептуально частью. Эта память не должна быть освобождена деструктором. (Если вы удалите свой телефонный номер из телефонной книги, вы не хотите, чтобы ваш телефон автоматически исчезал.)

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