Перейти к основному содержимому

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

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

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

#include <iostream>

class Base {
public:
virtual int what() { return 10; }
};

class Derived : public Base {
public:
virtual int what() { return 20; }
};

int main() {
Derived d;
Base* b = &d;
std::cout << b->what() << std::endl; // печатает 20
Base& c = d;
std::cout << c.what() << std::endl; // печатает 20
return 0;
}

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

#include <iostream>

class Base {
public:
virtual int what() { return 10; }
};

class Derived : public Base {
public:
virtual int what() { return 20; }
};

int main() {
Base* b = new Derived;
std::cout << b->Base::what() << std::endl; // 10
return 0;
}

При уничтожении объекта всегда вызываются деструкторы базовых классов. Поэтому деструкторы базовых классов должны быть виртуальными и всегда иметь реализацию.