ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 11) онлайн

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

Виртуальный означает видимый, но не существующий в реальности. Когда ис-

пользуются виртуальные функции, программа, которая, казалось бы, вызывает

функцию одного класса, может в этот момент вызывать функцию совсем другого

класса. А для чего вообще нужны виртуальные функции? Представьте, что име-

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

массиве и вызывались с помощью одного и того же выражения. Например, в гра-

фической программе MULTSHAP из главы 9 «Наследование» есть разные геомет-

рические фигуры: треугольник, шар, квадрат и т. д. В каждом из этих классов

есть функция draw(), которая прорисовывает на экране фигуры.

Теперь, допустим, вам захотелось создать картинку, сгруппировав некоторые

из этих элементов. Как бы сделать это без лишних сложностей? Подход к реше-

 

нию этой задачи таков: создайте массив указателей на все неповторяющиеся  элементы картинки:

 

shape* ptarr[100]; // массив из 100 указателей на фигуры

Если в этом массиве содержатся указатели на все необходимые геометриче-

ские фигуры, то вся картинка может быть нарисована в обычном цикле:

for(int j=0; j<N; j++)

ptarr[j]->draw();

Это просто потрясающая возможность! Абсолютно разные функции выпол-

няются с помощью одного и того же вызова! Если указатель в массиве ptarr

указывает на шарик, вызовется функция, рисующая шарик, если он указывает

на треугольник, то рисуется треугольник. Вот это и есть полиморфизм, то есть

различные формы. Функции выглядят одинаково — это выражение draw(), но

реально вызываются разные функции, в зависимости от значения ptarr[j]. Поли-

морфизм — одна из ключевых особенностей объектно-ориентированного про-

граммирования (ООП) наряду с классами и наследованием.

Чтобы использовать полиморфизм, необходимо выполнять некоторые усло-

вия. Во-первых, все классы (все эти треугольнички, шарики и т. д.) должны яв-

ляться наследниками одного и того же базового класса. В MULTSHAP этот класс

называется shape. Во-вторых, функция draw() должна быть объявлена виртуаль-

ной (virtual) в базовом классе.

Все это выглядит абстрактно, поэтому давайте напишем несколько неболь-

ших программ, которые выявят некоторые практические вопросы, чтобы потом

можно было собрать их воедино.

 

3