Справочное руководство по C++
Шрифт:
R.12.4 Деструкторы
Деструктором называется функция-член класса cl с именем ~cl, она используется для уничтожения значений типа cl непосредственно перед уничтожением объекта, содержащего их. Деструктор не имеет формальных параметров и для него нельзя
Деструкторы не наследуются. Если базовый класс или член имеют деструктор, а сам производный класс - нет, то создается стандартный деструктор, который вызывает деструкторы базовых классов и членов производного класса. Такие созданные деструкторы имеют спецификацию 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), например:
Явные вызовы деструкторов применяются редко. Примером этого может служить вызов деструктора для объектов, созданных в некоторой определенной адресной области с помощью операции 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*.
Если функция описана с двумя формальными параметрами, она вызывается с двумя параметрами, второй из которых показывает размер удаляемого объекта. Передаваемый размер определяется с помощью деструктора (если он есть) или по типу (статическому) указателя на удаляемый объект. Операция пройдет корректно, если тип указателя, заданного как фактический параметр, будет совпадать с типом объекта (а не будет, к примеру, просто типом указателя на базовый класс) или, если этот тип является типом указателя на базовый класс с виртуальным деструктором.