Виртуальные функции. Язык С++. (Лекция 10) презентация

Содержание

Слайд 2

Одним из основных принципов ООП (наряду с абстракцией данных, инкапсуляцией и наследованием) является

полиморфизм.
Полиморфи́зм — возможность для объектов с одинаковой спецификацией иметь различающиеся реализации. Язык программирования поддерживает полиморфизм, если классы с одинаковым интерфейсом могут иметь разную реализацию — например, реализация класса может быть изменена в процессе наследования.
Принцип полиморфизма: «Один интерфейс, множество реализаций».

Виртуальный – видимый, но не существующий в реальности.

Слайд 3

Пример: иерархия в животном мире
Предположим, что метод move(…) (двигаться) объявлен в базовом классе

animal. Тогда в производных классах этот метод может быть переопределен, так как разные виды животных могут двигаться по-разному (птицы – летать, рыбы – плавать, и т.д.).

Слайд 4

Формы полиморфизма

Полиморфизм включения (чистый полиморфизм)
позволяет эффективнее использовать объекты родственных классов. Например, дает

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

Слайд 5

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

класса, объявленный с использованием ключевого слова virtual.

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


class имя_класса
{
...
virtual метод_класса(аргументы);
...
}

Слайд 6

Применение виртуальных функций: коллекции родственных объектов

graph

triangle

circle

square

1) Пусть имеется иерархия, включающая в себя

несколько классов с одним общим предком.
Пример: геометрические фигуры на плоскости

предок – абстрактная фигура

наследники – конкретные формы

Слайд 7

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

фигур

элемент 0:
элемент 1:
элемент 2:
элемент 3:
элемент 4:

Слайд 8

В С++ такая коллекция может быть реализована как массив указателей на объекты базового

типа.

Пример: статический массив указателей на объекты класса graph
graph* collection[10]; // 10 указателей

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

Слайд 9

graph* collection[10];
graph G(...);
circle C(...);
rectangle R(...);
triangle T(...);
collection[0] =

&T;
collection[1] = &G;
collection[2] = &R;
collection[3] = &C;

Пример размещения в массиве объектов родственных классов

Слайд 10

Проблема
Этот способ размещения родственных объектов в массиве имеет существенный недостаток: объекты в массиве

теряют отличительные черты, так как становятся неотличимы от предка.
Вместо метода производного класса при вызове будет активирован метод базового класса.
collection[0]->draw();
collection[1]->draw(); ...

В обоих случаях будет активирована функция draw класса graph (вместо классов rectangle и triangle, соответственно).

Слайд 11

Для решения этой проблемы в языке С++ используют специальный инструмент – виртуальную функцию.
РЕШЕНИЕ:

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

...
virtual draw();
virtual resize(...);
...

Тогда при вызове перегруженного метода (например, draw) будет активирована функция производного класса (для rectangle – прорисовка прямоугольника, для triangle – треугольника и т.д.).

Слайд 12

Архитектура приложения

Слайд 13

Абстрактные классы

В рассмотренном нами примере класс graph выступает в качестве предка для классов

circle, square, triangle. Однако в основном модуле объекты этого класса никогда создаваться и использоваться не будут.
Базовый класс, объекты которого в программе не реализуются, называется абстрактным классом. Его назначение – быть родителем для одного или нескольких производных классов, объекты которых будут реализованы.
В нашем случае graph – абстрактный класс.

Слайд 14

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

Метод draw() класса graph никогда не будет вызываться напрямую, так как

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

Слайд 15

Объявление ЧВФ

Чистая виртуальная функция не содержит никаких операторов, и вообще не имеет тела.

Сразу после объявления ЧВФ внутри класса указывается выражение « = 0»
Таким образом, ЧВФ представляет собой только прототип функции, которая в последствии будет переопределена в производных классах.


class имя_абстрактного_класса
{
virtual имя_чвф(аргументы) = 0;
}

Слайд 16

Знак равенства здесь не имеет ничего общего с операцией присваивания. Конструкция = 0

сообщает компилятору о том, что функция является чистой виртуальной, а сам класс – абстрактным.
class graph
{
...
public:
graph(...);
virtual void draw() = 0;
};

При попытке создать объект класса graph компилятор выдаст сообщение об ошибке!

Слайд 17

Динамическая информация о типах

В С++ имеется возможность получать информацию о классе объекта прямо

во время выполнения программы.
Пример с графическим приложением: Объект какого класса (circle, square или triangle) находится под указателем collection[i]?
Одним из механизмов получения информации о типе объекта является использование оператора dynamic_cast.

Слайд 18

Проверка типа – dynamic_cast

Для использования оператора dynamic_cast компилятор должен задействовать механизм определения типа

на этапе выполнения – RTTI (Run-Time Type Information).
Кроме того, в программе должна быть подключена библиотека .
Имя файла: Виртуальные-функции.-Язык-С++.-(Лекция-10).pptx
Количество просмотров: 82
Количество скачиваний: 0