Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
С++ - ООП.doc
Скачиваний:
11
Добавлен:
21.09.2019
Размер:
399.87 Кб
Скачать

Пример использования виртуальных функций

Введем класс figure, который описывает плоскую фигуру, для вычисления площади которой достаточно двух измерений. В этом классе есть виртуальная функция show_area(), выводящая значение площади фигуры. На основе этого класса строятся другие классы triangle, rectangle, circle, для которых определена конкретная формула вычисления площади фигуры.

#include <iostream.h>

class figure {

protected:

double x,y;

public:

void set_dim(double i, double j=0)

{

x=i;

y=j;

}

virtual void show_area()

{

cout<<”\n Площадь не определена для этого класса \n”;

}

};

class triangle:public figure{

public:

void show_area()

{

cout<<”\n треугольник с высотой “<< x<<” и основанием “<<y;

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

}

};

class rectangle:public figure{

public:

void show_area()

{

cout<<”\n прямоугольник со сторонами “<< x<<” и “<<y;

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

}

};

class circle:public figure{

public:

void show_area()

{

cout<<”\n круг с радиусом “<< x;

cout<<” имеет площадь “<< 3.14159*x*x;<<endl;

}

};

void main(void)

{

figure f,*p; // объявление указателя на базовый тип

triangle t; // создание объектов производного типа

rectangle s;

circle c;

p=&f;

p->set_dim(1,2);

p->show_area();

p=&t;

p->set_dim(3,4);

p->show_area();

p=&s;

p->set_dim(5,6);

p->show_area();

p=&c;

p->set_dim(7);

p->show_area();

}

Чистые виртуальные функции и абстрактные типы

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

Первый способ – выдача предупреждающего сообщения (не всегда приемлем).

Другое решение проблемы – использование в С++ чистых виртуальных функций.

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

Форма определения чистой виртуальной функции следующая:

virtual тип имя-функции(список параметров) = 0;

тип – возвращаемый тип функции;

=0 - признак чистой виртуальной функции.

Пример, содержащий использование чистой виртуальной функции

#include <iostream.h>

class figure {

protected:

double x,y;

public:

void set_dim(double i, double j=0)

{

x=i;

y=j;

}

virtual void show_area() =0;

};

class triangle:public figure{

public:

void show_area()

{

cout<<”\n треугольник с высотой “<< x<<” и основанием “<<y<<;

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

}

};

class rectangle:public figure{

public:

void show_area()

{

cout<<”\n прямоугольник со сторонами “<< x<<” и “<<y;

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

}

};

class circle:public figure{

public:

void show_area()

{

cout<<”\n круг с радиусом “<< x;

cout<<” имеет площадь “<< 3.14159*x*x<<endl;

}

};

void main(void)

{

figure *p; // объявление указателя на базовый тип, создать объект нельзя!!

triangle t; // создание объектов производного типа

rectangle s;

circle c;

p=&f;

p->set_dim(1,2);

p->show_area();

p=&t;

p->set_dim(3,4);

p->show_area();

p=&s;

p->set_dim(5,6);

p->show_area();

p=&c;

p->set_dim(7);

p->show_area();

}

Объявление функции show_area() чистой виртуальной требует от всех производных классов собственных наполнений этой функции.

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