1) Ключевое слово virtual служит для создания виртуальных функций - которые должны быть переопределены в производном или производных классах.
2) Виртуальные функции позволяют использовать полиморфизм, когда имеются различные реализации виртуальных функций в классах наследниках от единого базового класса.
3) Ключевое слово virtual также может использоваться для создания виртуального наследования, которое позволяет избежать множественного наследования от нескольких классов с общим предком. При использовании виртуального наследования только один экземпляр класса-предка будет создан для всех классов-потомков, которые его наследуют.
4) Виртуальные функции реализуют динамическое связывание (dynamic binding) или так называемое позднее связывание (late binding), когда выбор подходящей функции выполняется на этапе выполнения программы. В этом случае выбор функции будет определяться типом объекта на который она ссылается, а не типом указателя (это будет реализация статического связывания)
#include <iostream> // cout, endl
using namespace std;
class Tree{ // Класс дерева
public: // Определяем публичные члены класса
void print(){ // Выводим информацию о классе
cout << "Tree print()" << endl;
}
virtual void print_v(){ // Выводим информацию о классе в виртуальной функции
cout << "Tree print_v()" << endl;
}
};
class Apple : public Tree{ // Класс яблока, производный от дерева
public: // Определяем публичные члены класса
void print(){
cout << "Apple print()" << endl;
}
void print_v(){ // Выводим информацию о классе в переопределенной виртуальной функции
cout << "Apple print_v()" << endl;
}
};
int main(){
Tree* tree_obj = new Tree(); // Создали объект класса Tree и указатель на него
tree_obj->print(); //Tree print()
tree_obj->print_v(); //Tree print_v()
Apple* apple_obj = new Apple(); // Создали объект класса Apple и указатель на него
apple_obj->print(); //Apple print()
apple_obj->print_v(); //Apple print_v()
tree_obj = apple_obj; // Присвоили указателю объекта базового класса адрес объекта производного класса
tree_obj->print(); //Tree print() Статическое связывание, метод остался из базового класса (типа указателя)
tree_obj->print_v(); //Apple print_v() Динамическое связывание, метод используется из производного класса (типа объекта)
}