Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lucik_op.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
2.88 Mб
Скачать

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

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

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

Рассмотрим отличия в работе программы при использовании виртуальных деструкторов и в случае их отсутствия на примере программы вычисляющей площади некоторых фигур (круг, прямоугольник).

#include "iostream.h"

#include "iomanip.h"

#include "string.h"

class Shape // базовый класс

{protected:

float s; // площадь фигуры

public:

Shape(char *fig) : s(0)

{ cout << "конструктор класса Shape (фигура "<< fig <<')'<< endl;}

virtual ~Shape()

{ cout << "деструктор класса Shape" << endl;}

void virtual print()

{cout<<s<<endl;}

void virtual area()=0;

};

class Circle : public Shape // производный класс Круг

{ int r;

public:

Circle(char *name,int r): Shape(name)

{ cout << "конструктор класса Circle "<<endl;

this->r=r;

}

~Circle()

{ cout << "деструктор класса Circle " << endl;}

void area();

};

class Bar : public Shape // производный класс Прямоугольник

{ int n,m;

public:

Bar(char *name,int n,int m): Shape(name)

{ cout << "конструктор класса Bar "<<endl;

this->n=n;

this->m=m;

}

~Bar()

{ cout << "деструктор класса Bar " << endl;}

void area();

};

void Circle::area()

{ s=r*r*3.14;

cout<<"Площадь круга = ";

this->print();

}

void Bar::area()

{ s=n*m;

cout<<"Площадь прямоугольника = ";

this->print();

}

int main()

{ Shape *fg1,*fg2;

fg1=new Circle("Круг",2);

fg2=new Bar("Прямоугольник",3,4);

fg1->area();

fg2->area();

delete fg1;

delete fg2;

return 1;

}

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

конструктор класса Shape (фигура Circle)

конструктор класса Circle

конструктор класса Shape (фигура Bar)

конструктор класса Bar

площадь круга =12.56

площадь прямоугольника =12

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

деструктор класса Shape

деструктор класса Bar

деструктор класса Shape

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

Если в классе имеются виртуальные функции, то желательно объявлять деструктор этого класса также виртуальным, даже если этого не требуется. Это может предотвратить возможные ошибки.

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