5.1. Переопределение составной функции

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

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

      #include <iostream.h>

      #include <conio.h>

      // Класс фрукты

      class fruit

            {

            public:

                  void show()

                        {

                        cout << "фрукты"<< endl;

                        }

            };

      // Класс яблоки

      class apple

            {

            public:

                  void show()

                        {

                        cout << "яблоки" << endl;

                        }

            };

      // Класс апельсины

      class orange

            {

            public:

                  void show()

                        {

                        cout << "апельсины" << endl;

                        }

            };

      void main()

            {

            clrscr();   // Очистка экрана

            // Создаём объекты

              fruit *a = (fruit *)new apple, *b = (fruit *)new orange;

            a -> show(); b -> show();    // Выводим сообщения

            getch();    // Ожидание нажатия клавиши

            }

В результате работы программы будет два раза выведено слово «фрукты», ибо оба оператора a->show() и b->show() вызовут функцию show() из базового класса. Для того чтобы решить проблему переопределения функций в производных классах, объекты которых заданы с помощью указателей на объекты базовых классов, применяются виртуальные функции. Они определяются в базовом классе следующим образом:

virtual тип_возвращаемого_значения  имя(параметры)

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

В частности, если в нашем примере в базовом классе указать

virtual void show(),

а остальной текст оставить без изменения, то программа выведет слова «яблоки» и «апельсины».

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

Виртуальные функции не могут быть статическими.