Справочное руководство по C++
Шрифт:
Деструктор может быть виртуальным.
В деструкторе можно вызывать функцию-член, см. §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, то он освобождает память для самого большего
Явные вызовы деструкторов применяются редко. Примером этого может служить вызов деструктора для объектов, созданных в некоторой определенной адресной области с помощью операции new. Размещение объектов в определенном адресном пространстве и последующее уничтожение их может потребоваться для использования специфических возможностей аппаратуры и для правильного функционирования оперативной памяти. Приведем пример:
Обозначения, использованные для явного вызова деструктора, можно использовать для имени любого простого типа, например,
Использование такой записи для типа, у которого нет деструктора, проходит бесследно. Допуская такую запись, мы разрешаем пользователям писать программу, не задумываясь над тем, есть ли данного типа деструктор.
R.12.5 Свободная память
Когда создается объект с помощью операции new, для получения свободной памяти вызывается (неявно) функция operator new (§R.5.3.3).
Если функция operator new не может выполнить запрос, она возвращает 0.
В классе X функция X::operator new является статическим членом, даже если она не описана явно как static. Первый ее параметр должен иметь тип size_t, - зависящий от реализации целочисленный тип, который определен в стандартном заголовочном файле ‹stddef.h›, и она должна возвращать значение типа void*, например:
Правила
выбора подходящей функции operator new обсуждаются в §R.5.3.3.В классе X функция X::operator delete является статическим членом, даже если она не описана явно как static. Первый ее параметр должен быть типа void* и можно добавлять второй параметр типа size_t. Она не может возвращать какое-либо значение и тип возвращаемого значения должен быть void, например:
В каждом классе можно описать только одну функцию operator delete, значит эта функция не может быть перегруженной. Глобальная функция operator delete имеет единственный параметр типа void*.
Если функция описана с двумя формальными параметрами, она вызывается с двумя параметрами, второй из которых показывает размер удаляемого объекта. Передаваемый размер определяется с помощью деструктора (если он есть) или по типу (статическому) указателя на удаляемый объект. Операция пройдет корректно, если тип указателя, заданного как фактический параметр, будет совпадать с типом объекта (а не будет, к примеру, просто типом указателя на базовый класс) или, если этот тип является типом указателя на базовый класс с виртуальным деструктором.
Для массивов объектов типа класс используются глобальные функции operator new и operator delete (§R.5.3.3, §R.5.3.4).
Поскольку функции X::operator new и X::operator delete статические, они не могут быть виртуальными. Функция operator delete, которая вызывается из деструктора для освобождения памяти, выбирается по обычным правилам областей видимости, например:
В этом примере память для объекта класса D выделяется с помощью D::operator new, а благодаря наличию виртуального деструктора, освобождается с помощью D::operator delete.
R.12.6 Инициализация
Объект класса без конструкторов, без частных или защищенных членов, без виртуальных функций и без базовых классов можно инициализировать с помощью списка инициализаторов (§R.8.4.1). Объект класса с конструктором должен инициализироваться или иметь стандартный конструктор (§R.12.1). Стандартный конструктор используется для объектов, которые не проходят явной инициализации.
R.12.6.1 Явная инициализация