Добавил:
Помощь с лабораторными, контрольными практическими и курсовыми работами по: - Инженерной и компьютерной графике - Прикладной механике Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 сем 1 курс С++ / Экзамен / Lektsii_Kurakina_2_semestr.pdf
Скачиваний:
12
Добавлен:
08.08.2022
Размер:
4.82 Mб
Скачать

7. Виртуальные функции. абстрактные классы

7.1 Указатели на производные типы

Указатели на производные типы — это одна из форм реализации динамического полиморфизма в С++. Указатель на базовый тип и производный тип зависимы.

Например: B_class -> D_class

В С++ всякий указатель на базовый класс В может быть также указателем на производный класс D.

B_class *p;

B_class b_ob;

D_class D_ob;

p=&B_ob;

p=&D_ob;

((D_class*)p)->f();

— приведение типа

При создании указателя на объект базового класса происходит присвоение как адрес объекта базового класса, так и производную класса.

Все элементы класса D, наследуемые от класса B, могут быть доступны через использование указателя p.

Если требуется иметь доступ к элементам, используется указатель на базовый класс, который надо привести к указателю на произвольный тип.

p — указатель на базовый класс

f — функция-член класса D.

Обратное неверно – нельзя использовать указатель на производный класс для присвоения ему адреса объекта базового класса.

При использовании операций инкремент, декремент указатель изменяется относительно базового типа.

Когда указатель на базовый класс указывает на производный, инкремент не делает его указывающим на следующий элемент производного класса.

7.2 Виртуальные функции

Виртуальные функции представляют собой функции-члены класса, которые переопределяются в производном классе. Механизм виртуальных функций обеспечивает динамический полиморфизм.

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

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

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

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

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

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

7.3 Пример

# include<iostream>

using namespace std;

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”;}};

class triangle:public figure{

public:void show_area(){

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

cout<<”имеет площадь”<<x*0,5+y;}};

class rectangle:public figure{

public:void show_area(){

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

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

class circle:public figure{

public:void show_area(){

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

cout<<”имеет площадь”<<3.14*x*x;}};

main()

{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(8); p->show_area();

}

Программа позволяет определить площади некоторых плоских фигур с использованием виртуальной функции. Виртуальная функция — определение площади.

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

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

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

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

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

Пример:

#include <iostream>

using namespace std;

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<<”треугольник с высотой”<<x<<”и основанием”<<y;

cout<<”имеет площадь”<<x*0,5+y;}};

class rectangle:public figure{

public:void show_area(){

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

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

class circle:public figure{

public:void show_area(){

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

cout<<”имеет площадь”<<3.14*x*x;}};

main()

{figure f,*p;

Соседние файлы в папке Экзамен