Выбрать главу

};

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

#include <iostream>

using namespace std;

class base {

 public:

  virtual void who() {

   cout << "Базовый класс.\n";

  }

};

class first_d : public base {

 public:

  void who() {

   cout << "Первый производный класс.\n";

  }

};

class second_d : public base {

 // Функция who() здесь не определена вообще.

};

int main()

{

 base base_obj;

 base *p;

 first_d first_obj;

 second_d second_obj;

 p = &base_obj;

 p->who(); // доступ к функции who() класса base

 р = &first_obj;

 p->who(); // доступ к функции who() класса first_d

 р = &second_obj;

 p->who(); /* Здесь выполняется обращение к функции who() класса base, поскольку в классе second_d она не переопределена. */

 return 0;

}

Теперь при выполнении этой программы на экран выводится следующее.

Базовый класс.

Первый производный класс.

Базовый класс.

Как подтверждают результаты выполнения этой программы, поскольку функция who() не переопределена классом second_d, то при ее вызове с помощью инструкции p->who() (когда член р указывает на объект second_obj) выполняется та версия функции who(), которая определена в классе base.

Следует иметь в виду, что наследуемые свойства спецификатора virtual являются иерархическими. Поэтому, если предыдущий пример изменить так, чтобы класс second_d был выведен из класса first_d, а не из класса base, то при обращении к функции who() через объект типа second_d будет вызвана та ее версия, которая объявлена в классе first_d, поскольку этот класс является "ближайшим" (по иерархическим "меркам") к классу second_d, а не функция who() из тела класса base. Эти иерархические зависимости демонстрируются на примере следующей программы.

#include <iostream>

using namespace std;

class base {

 public:

  virtual void who() {

   cout << "Базовый класс.\n";

  }

};

class first_d : public base {

 public:

  void who() {

   cout << "Первый производный класс.\n";

  }

};

// Класс second_d теперь выведен из класса first_d, а не из класса base.

class second_d : public first_d {

 // Функция who() не определена.

};

int main()

{

 base base_obj;

 base *p;

 first_d first_obj;

 second_d second_obj;

 р = &base_obj;

 p->who(); // доступ к функции who() класса base

 р = &first_obj;

 p->who(); // доступ к функции who() класса first_d

 р = &second_obj;

 p->who(); /* Здесь выполняется обращение к функции who() класса first_d, поскольку в классе second_d она не переопределена. */

 return 0;

}

Эта программа генерирует такие результаты.

Базовый класс.

Первый производный класс.

Первый производный класс.