Читать «Справочное руководство по C++» онлайн - страница 69

Бьярн Страустрап

Деструкторы не наследуются. Если базовый класс или член имеют деструктор, а сам производный класс - нет, то создается стандартный деструктор, который вызывает деструкторы базовых классов и членов производного класса. Такие созданные деструкторы имеют спецификацию 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; }