Язык С++ для системного программирования. Имена-этикетки. Класс как область действия, страница 16

1.  Вызывается деструктор производного класса.

2.  Вызываются деструкторы элементов, являющихся объектами классов.

3.  Вызывается деструктор базового класса.

22.6 Абстрактные классы и чистые виртуальные функции

Абстрактным является класс, в котором есть хотя бы одна чистая виртуальная функция. Напомним ее вид:

virtual тип_результата имя_функции()=0

Она может рассматриваться как встроенная (inline-функция), тело которой определено как =0 (чистый спецификатор). Чистая виртуальная переопределяется в производных классах. Другими словами, в абстрактном классе только объявляются функции с определенными именами, а конкретное содержание того, что будут делать эти функции, будет определено в производных классах. Ясно, что из-за этого абстрактный класс может использоваться только в качестве базового для других классов. К абстрактным классам применимы следующие правила:

1.  Абстрактный класс не может использоваться в качестве аргумента функции или типа возвращаемого результата.

2.  Абстрактный класс нельзя использовать в явном преобразовании.

3.  Нельзя определить объект абстрактного класса (глобальную/локальную переменную или элемент данных).

4.  Можно определять указатель или ссылку на абстрактный класс.

5.  Если класс, производный от абстрактного, не определяет все чистые виртуальные функции абстрактного класса, он также является абстрактным.

Рассмотрим пример. У плоской фигуры есть общие элементы данных: периметр(perimetr) и площадь(plo). Есть конкретные плоские фигуры: прямоугольник (rectangle) и круг (crug). Для каждой из этих фигур имеются свои элементы-данные и по-разному вычисляются периметр (длина окружности для круга) и площадь. При программировании удобно, чтобы члены функции ввода/вывода данных, а также функции вычисления периметра и площади имели одинаковые имена как при работе с прямоугольником, так и при вычислении параметров круга. Сделаем class fiqure базовым. В нем опишем чистые виртуальные функции для ввода, вывода данных, вычисления периметра и вычисления площади. Определим два производных класса: class crug и class rectangle. В них будут переопределены чистые виртуальные функции.

#include <;stdio.h>
 
#include <math.h>
 
class fiqure
 
 {
 
protectrd:
 
float perimeter, plo;
 
 public:
 
virtual void input()=0;//Ввод данных
 
virtualvoidoutput()=0;//Вывод результатов
 
virtualvoidl()=0;//Вычисление периметра
 
virtualvoids()=0;// Вычисление площади
 
 }
 
class crug: public fiqure
 
 {
 
float R; //Радиус
 
public:
 
void input()//virtual можно не писать
 
{
 
puts("Введите радиус")
 
scanf("%f,&R);
 
 }
 
void output()
 
printf("Для круга длина окружности (perimetr)=%f, площадь=%f\n", perimetr, plo);
 
 }
 
void l()
 
 {
 
perimeter=2*M_PI*R;
 
 }
 
void s()
 
 {
 
plo=M_PI*R*R
 
 }
 
 };
 
class reet: public fiqure
 
 {
 
float a,b;//ширина и длина
 
public:
 
voidinput()
 
 {
 
puts("Введите а и в");
 
scanf("%f%f,&a, &b);
 
 }
 
void output()
 
{
 
printf("Для прямоугольника периметр=%f площадь =%f \n"perimetr, plo);
 
}
 
 void l()
 
{
 
perimetr=2*(a+b);
 
 }
 
void s()
 
 {
 
plo=a*b;
 
}
 
 };
 
voidmain()
 
 {
 
fiqure*p=newcrug;/*В указатель р на базовый класс заносится адрес, выделенный под объект производного класса crug*/
 
p→input();
 
p→l();
 
p→s();
 
poutput();/*Последовательно
вызываются функции класса crug*/
 
p=new
rectangle;
 
p→input();
 
p→l();
 
p→s();
 
p→output();
 
}

После занесения в указатель р адреса для объекта класса rectangle происходит вызов соответствующих виртуальных функций класса rectangle.

23.1 Классы потоков языка С++