Объектно-ориентированное программирование — Деструктор

Деструктор

Деструктором называется составная функция класса, которая вызывается перед разрушением объекта. Это означает, что деструктор вызывается в следующих случаях:

· при выходе из области видимости;

· при выполнении операции delete для объектов, размещенных в динамической памяти;

· непосредственно, как составная функция.

Уже обсуждалось, что класс может иметь несколько конструкторов, все эти конструкторы имеют одинаковое имя, совпадающее с именем класса. Приведём правила определения деструкторов:

· класс имеет ровно один деструктор;

· имя деструктора совпадает с именем класса с добавленным впереди символом тильды «~»;

· деструктор не имеет аргументов и не имеет возвращаемого значения.

Если же деструктор не определить явно, то он будет определен по умолчанию, как составная функция

~ имя_класса() {};

и будет находиться в открытой части класса.

Пример. Определим класс, объектом которого является стек, состоящий из элементов, размещающихся в массиве целых чисел. Поскольку конструктор будет захватывать динамическую память, то необходим деструктор, который эту память будет освобождать после окончания работы со стеком.

#include

#include

// Класс — целочисленный стек

class IntStack

{

// Закрытые элементы

int *v; // Массив под стек

int size, top; // Размер стека и положение вершины

public: // Общедоступные элементы

IntStack(int n = 10): size(n), top(n) // Конструктор

{

v = new int[n]; // Выделение памяти под массив (стек)

}

~IntStack() // Деструктор

{

delete []v; // Освобождение памяти

}

int& operator++(int); // Перегрузка постфиксной операции ++

int operator--(); // Перегрузка префиксной операции --

};

int& IntStack::operator++(int) // Перегрузка постфиксной операции ++

{

return v[--top];

}

int IntStack::operator--() // Перегрузка префиксной операции --

{

return v[top++];

}

int main()

{

clrscr(); // Очистка экрана

IntStack *ps = new IntStack(20); // Создание стека ps

// в динамической памяти

IntStack s; // Создание стека s (по умолчанию 10 элементов)

for(int i = 0; i < 10; i++)

s++ = i; // запись чисел 0,1,2,... в стек

cout<<"Содержимое стека:\n";

for(int j = 0; j < 10; j++)

cout << --s << '\n'; // Чтение из стека

(*ps)++ = 100; // Пример занесения в стек ps числа 100

s.~IntStack(); // Явное разрушение стека s

delete ps; // Разрушение стека ps

getch(); // Ожидание нажатия клавиши

return 0; // Выход из программы

}

В результате работы этой программы на экран будут выведены числа 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 , каждое с новой строки.

Пример. Определим класс трассировочного типа, позволяющий отслеживать вход в блок и выход из блока программы, для которого определен объект этого класса. Воспользуемся с этой целью свойством запуска конструктора при вхождении в блок, содержащий объект, инициализируемый этим конструктором. При выходе из блока будет вызываться деструктор.

#include

#include

#include

// Трассировочный класс

class trace

{

const char* msg;

public:

trace(char *m): msg(m) // Конструктор

{

// Вывод сообщения о входе в блок

fprintf(stderr, "Входим в %s\n", msg);

}

~trace() // Деструктор

{

// Вывод сообщения о выходе из блока

fprintf(stderr, "Выходим из %s\n", msg);

}

};

void subr()

{

trace t("subr");

}

int main()

{

clrscr(); // Очистка экрана

trace t("main");

cout<<'\n'; // Перевод строки

subr();

cout<<'\n'; // Перевод строки

for(int i = 0; i < 5; i++)

{

trace t("internal");

}

cout<<'\n'; // Перевод строки

return 0; // Выход из программы

}

Результаты работы программы

Входим в main

Входим в subr

Выходим из subr

Входим в internal

Выходим из internal

Входим в internal

Выходим из internal

Входим в internal

Выходим из internal

Входим в internal

Выходим из internal

Входим в internal

Выходим из internal

Выходим из main

Вы здесь: Главная Информатика Программирование Объектно-ориентированное программирование