Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вариант_№32.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
363.52 Кб
Скачать

Виртуальные деструкторы

Методы и деструкторы (но не конструкторы !) могут быть виртуальны­ми. Виртуальные деструкторы обычно применяются, когда в некотором классе необходимо удалить объекты производного класса, на которые ссылаются ука­затели на базовый класс. Типичной является ситуация, когда динамически со­здается объект производного класса, а используется указатель на базовый класс.

Пример 38.

Рассмотрим простое наследование по схеме Base <- Derive1 <- Derive2. Программа (на основе примера 36) иллюстрирует порядок работы конструкто­ров и деструкторов в классах при динамическом выделении памяти объекту производного класса через указатель на базовый класс и уничтожение объектов с использованием виртуального деструктора. Если объявить деструктор базово­го класса виртуальным, то все деструкторы производных классов также яв­ляются виртуальными.

#include<iostream.h>

#include<conio.h>

class Base

{ public:

Base () { cout << "Конструктор базового класса Base\n"; }

virtual ~Base () { cout << "Деструктор базового класса Base\n"; }

};

class Derive1: public Base

{ public:

Derive1 () { cout << "Конструктор производного класса Derive1\n"; }

~Derive1 () { cout << "Деструктор производного класса Derive1\n"; }

};

class Derive2: public Derive1

{ public:

Derive2 () { cout << "Конструктор производного класса Derive2\n"; }

~Derive2 () { cout << "Деструктор производного класса Derive2\n"; }

};

void main ()

{ clrscr ();

Base *pb = new Derive2; // выделение памяти объекту Derive2

if (! pb)

{ cout << "Недостаточно памяти\n";

return 1; // аварийное окончание программы

}

cout << endl;

delete pb; // вызов всех деструкторов производных и базового классов

return 0;

}

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

Конструктор базового класса Base

Конструктор производного класса Derive1

Конструктор производного класса Derive2 // создание объекта типа Derive2

Деструктор производного класса Derive2

Деструктор производного класса Derive1

Деструктор базового класса Base // уничтожение объекта типа Derive2

Комментарии к программе:

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

Пример 39.

Рассмотрим модифицированную программу на основе примеров 33 и 35, в которой используется абстрактный базовый класс Figure с чистой виртуальной функцией show_area() и виртуальным деструктором. Базовый класс Figure описывает плоскую фигуру с двумя измерениями, которые задаются конструк­тором со вторым параметром по умолчанию. Нельзя создать объект данного класса, но можно определить указатель на тип класса. От этого класса на осно­ве расширяющегося наследованиия строятся производные классы по схеме: Figure <- (Triangle, Rectangle, Circle). В производных классах определены свои функции show_area().

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

#include<iostream.h>

#include<conio.h>

class Figure // абстрактный базовый класс

{ protected: // защищенные элементы, доступные в производных классах

double x, y;

public:

Figure (double i, double j=0) // конструктор с параметром по умолчанию

{ x = i, y = j; // задание измерений фигур

cout<<"Конструктор базового класса Figure\n";

}

virtual void show_area() = 0; // чистая виртуальная функция

virtual ~Figure () // виртуальный деструктор Figure { cout<<"Деструктор базового класса Figure\n";}

};

class Triangle: public Figure // производный класс Triangle

{ public:

Triangle (double i, double j): Figure ( i, j) // конструктор Triangle

{ cout<<"Конструктор Triangle\n"; }

void show_area() // виртуальная функция Triangle

{ cout<<"Треугольник с высотой "<< x <<" и основанием "<< y;

cout<<" имеет площадь = "<< x*0.5*y <<endl;

}

~Triangle() // виртуальный деструктор Triangle

{ cout<<"Деструктор классаTriangle \n";}

};

class Rectangle: public Figure // производный класс Rectangle

{ public:

Rectangle (double i, double j): Figure ( i, j) // конструктор Rectangle

{ cout<<"Конструктор Rectangle\n"; }

void show_area() // виртуальная функция Rectangle

{ cout<<"Прямогольник со сторонами "<< x <<" и "<< y;

cout<<" имеет площадь = "<< x*y <<endl;

}

~Rectangle() // виртуальный деструктор Rectangle { cout<<"Деструктор класса Rectangle\n"; }

};

class Circle: public Figure // производный класс Circle

{ public:

Circle (double i): Figure ( i) // конструктор Circle {cout<<"Конструктор Circle\n"; }

void show_area() // виртуальная функция Circle

{ cout<<"Круг с радиусом "<< x;

cout << " имеет площадь = " << 3.14*x*x << endl;

}

~Circle() // виртуальный деструктор Circle { cout<<"Деструктор класса Circle\n"; }

};

void main ()

{ clrscr();

cout << "Работа программы:\n";

Figure *p; // объявление указателя класса Figure

Triangle t (3,4); // создание объекта класса Triangle

Rectangle r (5,6); // создание объекта класса Rectangle

Circle c (2); // создание объекта класса Circle

p = &t; // базовый указатель на объект типа Triangle

p -> show_area(); // вывод сообщения о площади объекта типа Triangle

p = &r; // базовый указатель на объект типа Rectangle

p -> show_area(); // вывод сообщения о площади объекта типа Rectangle

p = &c; // базовый указатель на объект типа Circle

p -> show_area(); // вывод сообщения о площади объекта типа Circle

}

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

Работа программы:

Конструктор базового класса Figure

Конструктор Triangle

Конструктор базового класса Figure

Конструктор Rectangle

Конструктор базового класса Figure

Конструктор Circle

Треугольник с высотой 3 и основанием 4 имеет площадь = 6

Прямогольник со сторонами 5 и 6 имеет площадь = 30

Круг с радиусом 2 имеет площадь = 12.56

Деструктор класса Circle

Деструктор базового класса Figure

Деструктор класса Rectangle

Деструктор базового класса Figure

Деструктор классаTriangle

Деструктор базового класса Figure

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]