R.12.4 Деструкторы
Деструктором называется функция-член класса cl с именем ~cl, она
используется для уничтожения значений типа cl непосредственно перед
уничтожением объекта, содержащего их. Деструктор не имеет формальных
параметров и для него нельзя задать тип возвращаемого значения
(даже void). Нельзя применять операцию взятия адреса для деструктора.
Можно вызывать деструктор для объектов со спецификацией const или
volatile, но сам деструктор нельзя описывать с этими спецификациями
($$R.9.3.1). Деструктор не может быть и статическим.
Деструкторы не наследуются. Если базовый класс или член имеют
деструктор, а сам производный класс - нет, то создается стандартный
деструктор, который вызывает деструкторы базовых классов и членов
производного класса. Такие созданные деструкторы имеют спецификацию
public.
Тело деструктора выполняется прежде деструкторов для объектов,
являющихся членами. Деструкторы для нестатических объектов, являющихся
членами, выполняются прежде, чем деструкторы для базовых классов.
Деструкторы для невиртуальных базовых классов выполняются прежде,
чем деструкторы для виртуальных базовых классов. Деструкторы для
невиртуальных базовых классов выполняются в порядке, обратном их
описанию в производном классе. Деструкторы виртуальных базовых
классов выполняются в порядке, обратном появлению их при обходе
снизу и слева-направо ацикличного направленного графа базовых
классов. Здесь "слева-направо" означает порядок появления имен
базовых классов, который был при описании их в производном классе.
Деструкторы для элементов массива вызываются в порядке,
обратном вызовам при их построении.
Деструктор может быть виртуальным.
В деструкторе можно вызывать функцию-член, см. $$R.12.7.
Объект класса с деструктором не может быть членом объединения.
Деструкторы вызываются неявно в следующих случаях:
(1) когда исчезают из области видимости объекты auto ($$R.3.5)
или временные объекты ($$R.12.2, $$R.8.4.3);
(2) при завершении программы ($$R.3.4) для построенных статических
объектов ($$R.3.5);
(3) благодаря обращению к операции delete ($$R.5.3.4) для объектов,
созданных с помощью операции new ($$R.5.3.3);
(4) при явном вызове.
Когда деструктор вызывается операцией delete, то он освобождает
память для самого большего из производных классов ($$R.12.6.2) того
объекта, который использовал операцию delete() ($$R.5.3.4),
например:
class X {
// ...
public:
X(int);
~X();
};
void g(X*);
void f() // общий случай
{
X* p = new X(111); // размещение и инициализация
g(p);
delete p; // освобождение и удаление
}
Явные вызовы деструкторов применяются редко. Примером этого может
служить вызов деструктора для объектов, созданных в некоторой
определенной адресной области с помощью операции new. Размещение
объектов в определенном адресном пространстве и последующее
уничтожение их может потребоваться для использования специфических
возможностей аппаратуры и для правильного функционирования оперативной
памяти. Приведем пример:
void* operator new(size_t, void* p) { return p; }
void f(X* p);
static char buf[sizeof(X)];
void g() // редкий, специальный случай
{
X* p = new(buf) X(222); // размещение в buf[] и инициализация
f(p);
p->X::~X(); // удаление
}
Обозначения, использованные для явного вызова деструктора, можно
использовать для имени любого простого типа, например,
int* p;
// ...
p->int::~int();
Использование такой записи для типа, у которого нет деструктора,
проходит бесследно. Допуская такую запись, мы разрешаем пользователям
писать программу, не задумываясь над тем, есть ли данного типа
деструктор.
- * Справочное руководство r.1 Введение
- R.1.1 Обзор
- R.1.2 Запись синтаксиса
- R.2 Соглашения о лексических понятиях
- R.2.1 Лексемы
- R.2.3 Идентификаторы
- R.2.4 Служебные слова
- R.2.5 Литералы
- R.2.5.1 Целые константы
- R.2.5.2 Символьные константы
- R.2.5.3 Константы с плавающей точкой
- R.2.5.4 Строки литералов
- R.3 Основные понятия
- R.3.1 Описания и определения
- R.3.2 Область видимости
- R.3.3 Программа и связывание
- R.3.4 Начало и окончание программы
- R.3.5 Классы памяти
- R.3.6 Типы
- R.3.6.1 Основные типы
- R.3.6.2 Производные типы
- R.3.6.3 Имена типов
- R.3.7 Адреса
- R.4 Стандартные преобразования
- R.4.1 Стандартные преобразования для целочисленных
- R.4.2 Преобразования целочисленных
- R.4.3 Значения с плавающей точкой и двойной точностью
- R.4.4 Целочисленные и числа с плавающей точкой
- R.4.6 Преобразования указателей
- R.4.7 Преобразования ссылок
- R.4.8 Указатели на члены
- R.5 Выражения
- R.5.1 Первичные выражения
- R.5.2 Постфиксные выражения
- R.5.2.1 Индексация
- R.5.2.2 Вызов функции
- R.5.2.3 Явные преобразования типа
- R.5.2.4 Доступ к члену класса
- R.5.2.5 Инкремент и декремент
- R.5.3 Унарные операции
- R.5.3.1 Инкремент и декремент
- R.5.3.2 Операция sizeof
- R.5.3.3 Операция new
- R.5.3.4 Операция delete
- R.5.4 Явное преобразование типа
- R.5.5 Операции указатель-на-член
- R.5.6 Мультипликативные операции
- R.5.8 Операции сдвига
- R.5.9 Операции отношения
- R.5.10 Операции сравнения на равенство
- R.5.11 Поразрядная операция и
- R.5.12 Поразрядная (исключающая) операция или
- R.5.13 Поразрядная (включающая) операция или
- R.5.14 Логическая операция и
- R.5.15 Логическая операция или
- R.5.16 Операция условия
- R.5.17 Операции присваивания
- R.5.18 Операция запятая
- R.5.19 Выражения-константы
- R.6 Операторы
- R.6.1 Помеченный оператор
- R.6.2 Оператор-выражение
- R.6.3 Составной оператор или блок
- R.6.4 Выбирающий оператор
- R.6.4.1 Оператор if
- R.6.4.2 Оператор переключателя
- R.6.5 Операторы цикла
- R.6.5.1 Оператор while
- R.6.5.2 Оператор do
- R.6.5.3 Оператор for
- R.6.6 Операторы перехода
- R.6.6.1 Оператор break
- R.6.6.2 Оператор continue
- R.6.6.3 Оператор return
- R.6.6.4 Оператор goto
- R.6.7 Оператор описания
- R.6.8 Разрешение неоднозначности
- R.7 Описания
- R.7.1 Спецификации
- R.7.1.1 Спецификации класса памяти
- R.7.1.2 Спецификации функций
- R.7.1.3 Спецификация typedef
- R.7.1.4 Спецификация шаблона типа
- R.7.1.5 Спецификация friend
- R.7.1.6 Спецификация типа
- R.7.2 Описание перечисления
- R.7.3 Описания asm
- R.7.4 Спецификации связи
- R.8 Описатели
- R.8.1 Имена типов
- R.8.1.1 Устранение неоднозначности
- R.8.2 Смысл описателей
- R.8.2.1 Указатели
- R.8.2.2 Ссылки
- R.8.2.3 Указатели на члены
- R.8.2.4 Массивы
- R.8.2.5 Функции
- R.8.3 Определения функций
- R.8.4 Инициализаторы
- R.8.4.1 Агрегат
- R.8.4.2 Символьные массивы
- R.8.4.3 Ссылки
- R.9 классы
- R.9.1 Имена класса
- R.9.2 Члены класса
- R.9.3 Функции-члены
- R.9.3.1 Указатель this
- R.9.3.2 Функции-члены со спецификацией inline
- R.9.4 Статические члены
- R.9.5 Объединения
- R.9.6 Битовые поля
- R.9.7 Вложенные описания классов
- R.9.8 Описания локальных классов
- R.9.9 Имена локальных типов
- R.10 Производные классы
- R.10.1 Множественные базовые классы
- R.10.1.1 Неоднозначности
- R.10.2 Виртуальные функции
- R.10.3 Абстрактные классы
- R.10.4 Сводка правил области видимости
- R.11 Контроль доступа к членам
- R.11.1 Спецификации доступа
- R.11.2 Спецификации доступа для базовых классов
- R.11.3 Описания доступа
- R.11.4 Друзья
- R.11.5 Доступ к защищенным членам
- R.11.6 Доступ к виртуальным функциям
- R.11.7 Множественный доступ
- R.12 Специальные функции-члены
- R.12.1 Конструкторы
- R.12.2 Временные объекты
- R.12.3 Преобразования
- R.12.3.1 Преобразование с помощью конструктора
- R.12.3.2 Функции преобразования
- R.12.4 Деструкторы
- R.12.5 Свободная память
- R.12.6 Инициализация
- R.12.6.1 Явная инициализация
- R.12.6.2 Инициализация членов и базовых классов
- R.12.7 Конструкторы и деструкторы
- R.12.8 Копирование объектов класса
- R.13 Перегрузка
- R.13.1 Сопоставление описаний
- R.13.2 Сопоставление параметров
- R.13.3 Адрес перегруженной функции
- R.13.4 Перегруженные операции
- R.13.4.1 Унарные операции
- R.13.4.2 Бинарные операции
- R.14.2 Шаблоны типов для классов
- R.14.3 Эквивалентность типов
- R.14.4 Шаблоны типа для функций
- R.14.5 Описания и определения
- R.14.6 Функции-члены шаблонов типа
- R.14.7 Друзья
- R.14.8 Статические члены и переменные
- R.15 Обработка особых ситуаций r.15.1 Обработка особых ситуаций
- R.15.2 Запуск особой ситуации
- R.15.3 Конструкторы и деструкторы
- R.15.4 Обработка особой ситуации
- R.15.5 Спецификации особых ситуаций
- R.15.6 Специальные функции
- R.15.6.1 Функция terminate()
- R.15.6.2 Функция unexpected()
- R.15.7 Особые ситуации и правила доступа
- R.16 Препроцессорная обработка
- R.16.1 Фазы препроцессорной обработки
- R.16.2 Триграфные последовательности
- R.16.3 Макроопределение и макроподстановка
- R.16.3.1 Операция #
- R.16.3.2 Операция ##
- R.16.3.3 Повторный просмотр и дальнейшие подстановки
- R.16.3.4 Область видимости макроимен и конструкция #undef
- R.16.4 Включение файлов
- R.16.5 Условная трансляция
- R.16.6 Управление строками
- R.16.7 Команда error
- R.16.8 Команда pragma
- R.16.9 Пустая директива
- R.16.10 Предопределенные макроимена
- R.17 Приложение a: Сводка грамматики
- R.17.1 Служебные слова
- R.17.2 Выражения
- R.17.3 Описания
- R.17.4 Описатели
- R.17.5 Описания класса
- R.17.6 Операторы
- R.17.7 Препроцессор
- R.17.8 Шаблоны типа
- R.17.9 Обработка особых ситуаций
- R.18 Приложение b: Совместимость
- R.18.1 Расширения
- R.18.2.1 Как бороться с расхождениями
- R.18.3 Анахронизм
- R.18.3.1 Определения функций старого стиля
- R.18.3.4 Приведение указателей на функцию-член
- R.18.3.5 Невложенность классов
- Список служебных слов
- Указатель
- * Примеры *