};
Если производный класс не переопределяет виртуальную функцию, то используется функция, определенная в базовом классе. Например, проверим, как поведет себя версия предыдущей программы, если в классе 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;
}
Эта программа генерирует такие результаты.
Базовый класс.
Первый производный класс.
Первый производный класс.