Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по С++ глава 3.doc
Скачиваний:
6
Добавлен:
05.11.2018
Размер:
187.9 Кб
Скачать

3.5.2. Деструкторы

Можно определить специальную функцию-член, называемую деструктором и автоматически вызываемую всякий раз при уничтожении объекта. Имя деструктора совпадает с именем класса и содержит дополнительный символ префикса «~». По аналогии с конструктором деструктор определяется без задания типа возвращаемого значения (нельзя указать даже void). Однако в отличие от конструктора ему нельзя передавать параметры. Например, если класс называется CMessage, его деструктор определяется следующим образом.

~CMessage()

{

// код деструктора ...

}

Деструктор может выполнять любые задачи, необходимые для удаления объекта. Например, конструктор класса (CMessage) выделяет блок памяти для хранения строки сообщения, а деструктор освобождает память непосредственно перед удалением экземпляра класса.

#include <string.h>

class CMessage

{

private:

char *Buffer; // хранит строку сообщения

public:

CMessage ()

{

Buffer = new char ('\0'); // инициализирует буфер

// пустой строкой

}

~CMessage () // деструктор класса

{

delete [] Buffer; // освобождает память

}

void Display ()

{

// код для отображения содержимого переменной Buffer ...

}

void Set (char *String) // запись новой строки сообщения

{

delete [] Buffer;

Buffer = new char [strlen (String) + 1];

strcpy (Buffer, String);

}

};

3.5.3. Когда вызываются конструкторы и деструкторы

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

  • Объект определен глобально (т. е. вне любой функции). Конструктор вызывается в самом начале программы до вызова функции main (или WinMain в программе, работающей в среде Windows), деструктор – по окончании программы.

  • Объект определен локально (т.е. внутри функции). Конструктор вызывается, когда поток управления достигает определения объекта, деструктор – при выходе за пределы блока, в котором определен объект (т.е. когда объект выходит из области видимости).

  • Объект определен локально с использованием спецификатора static. Конструктор вызывается, когда поток управления впервые достигает определения объекта, деструктор – в конце программы;

  • Объект создан динамически с использованием оператора new. Конструктор вызывается при создании объекта, а деструктор – когда объект явно уничтожается с использованием оператора delete. Если этого не происходит, деструктор не будет вызван никогда.

Массивы объектов

В языке C++ можно определить массив объектов, как показано в следующем примере.

CRectangle RectTable [10];

CRectangle – это класс, рассмотренный в предыдущей главе. Массив объектов также можно создать динамически.

CRectangle *RectTable = new CRectangle [10];

В обоих случаях при создании объекта компилятор вызывает конструктор по умолчанию для каждого элемента массива. Когда же массив уничтожается, компилятор вызывает деструктор для каждого такого элемента (полагая, что деструктор определен для класса). Если класс не имеет конструктора по умолчанию, возникает ошибка.

Если вы определили именованный массив объектов (как в первом примере), то каждый элемент массива можно инициализировать, передавая в конструктор требуемые значения. Этот прием описан в параграфе «Инициализация массивов» (гл. 5).

Однако если массив создан динамически с использованием оператора new, нельзя обеспечить инициализацию отдельных элементов, так как компилятор всегда вызывает конструктор по умолчанию для каждого элемента. Кроме того, при уничтожении динамически созданного массива нужно в оператор delete добавить символы массива «[]».

delete [] RectTable;

Если символы «[]» отсутствуют, то компилятор вызовет деструктор только для первого элемента массива.

Примечание

Конструкторы для элементов массива вызываются в порядке возрастания адресов, а деструкторы – в обратном порядке.