Виртуальные функции
В языке программирования 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;
}
При уничтожении объекта всегда вызываются деструкторы базовых классов. Поэтому деструкторы базовых классов должны быть виртуальными и всегда иметь реализацию.