Виртуальные функции - IsuiGit/borodaedu GitHub Wiki
#include <iostream>
class Person {
public:
Person(std::string name) : name(name) {};
void print() { std::cout << "Name: " << name << std::endl; }
private:
std::string name;
};
class Employee : public Person {
public:
Employee(std::string name, std::string company) : Person(name), company(company) {};
void print() { Person::print(); std::cout << company << std::endl; }
private:
std::string company;
};
int main()
{
// Создание экземпляров класса и вызов внутренних методов...OK!
Person tom("tom");
tom.print();
Employee bob("bob", "Microsoft");
bob.print();
std::cout << "Objects tests passed\n";
// Создание указателей на тип Person и вызов print()...failed!
Person kate("kate");
Person* person{ &kate };
std::cout << "Kate (Person) calls print()\n";
person->print();
Employee andrew("andrew", "Amazon");
person = &andrew;
std::cout << "Andrew (Employee) calls print()\n";
person->print();
}
Виртуальная (virtual) функция - тип функций классов, предназначенные для динамического связывания реализаций методов между собой, для построения правильного стека вызовов наследных классов.
#include <iostream>
class Person {
public:
Person(std::string name) : name(name) {};
virtual void print() { std::cout << "Name: " << name << std::endl; } // <- теперь эта функция виртуальная и динамически связана с классами-наследниками
private:
std::string name;
};
...Override - ключевая лексема в явном виде указывающая компилятору на перезапись виртуальной функции на этапе компиляции. Необходимо для отмены эффекта затенения (затирания), предусмотренного в качестве механизма защиты при компиляции.
#include <iostream>
class Person {
public:
Person(std::string name) : name(name) {};
virtual void print() { std::cout << "Name: " << name << std::endl; } // <- теперь эта функция виртуальная и динамически связана с классами-наследниками
private:
std::string name;
};
class Employee : public Person {
public:
Employee(std::string name, std::string company) : Person(name), company(company) {};
void print() override { Person::print(); std::cout << company << std::endl; } // <- а эта функция защищена от затирания с помощью override
private:
std::string company;
};
...- На этапе компиляции создается специальная таблица
vtable. - В объектах, использующих
virtualфункции, создается указатель на адрес описания функции в классе. - Виртуальная функция ссылается на таблицу
vtable, и находит конкретную реализацию для конкретного класса, в текущем контексте.

final - спецификатор, определяющий запрет на изменение виртуальных функций в производных классах, с тем же именем и сигнатурой.
class Person{
public:
virtual void print() final{
...
}
}
class Employee{
public:
void print() override { // <- компилятор выдаст ошибку переопределения функции защищенной от перезаписи
...
}
}