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

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

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

  • Виртуальная функция — это функция-член класса, которая может быть переопределена в производных классах. Использование виртуальных функций позволяет реализовать полиморфизм в C++.
  • Синтаксис: ключевое слово virtual перед объявлением функции в базовом классе.

Основные моменты

  • Виртуальная функция определяется в базовом классе и может быть переопределена в производных классах.
  • Если функция переопределяется в производном классе, вызов функции через указатель или ссылку на базовый класс приведет к вызову версии функции из производного класса.

Пример

#include <iostream>
using namespace std;
class Base {
public:
virtual void show() {
cout << "Base class show function called" << endl;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class show function called" << endl;
}
};
int main() {
Base* basePtr;
Derived derivedObj;
basePtr = &derivedObj;
// Виртуальный вызов
basePtr->show(); // Вывод: Derived class show function called
return 0;
}

Виртуальные вызовы

  • Виртуальные вызовы происходят, когда виртуальная функция вызывается через указатель или ссылку на базовый класс. В зависимости от фактического типа объекта, на который указывает указатель (или ссылку), вызывается соответствующая версия функции.
  • Это позволяет динамически определять, какая версия функции должна быть вызвана во время выполнения программы, а не во время компиляции.

Основные моменты

  • Виртуальные вызовы обеспечивают механизм полиморфизма в C++, позволяя объектам разных типов обрабатывать вызовы функции по-разному.
  • Таблица виртуальных функций (vtable) и указатель на таблицу виртуальных функций (vptr) используются для реализации виртуальных вызовов в C++.
  • Когда виртуальная функция вызывается, компилятор использует vptr для поиска правильной функции в vtable, соответствующей фактическому типу объекта.

Пример, иллюстрирующий виртуальные вызовы

#include <iostream>
using namespace std;
class Animal {
public:
virtual void sound() {
cout << "Some generic animal sound" << endl;
}
virtual ~Animal() {}
};
class Dog : public Animal {
public:
void sound() override {
cout << "Bark" << endl;
}
};
class Cat : public Animal {
public:
void sound() override {
cout << "Meow" << endl;
}
};
void makeSound(Animal* animal) {
animal->sound(); // Виртуальный вызов
}
int main() {
Dog dog;
Cat cat;
makeSound(&dog); // Вывод: Bark
makeSound(&cat); // Вывод: Meow
return 0;
}

Резюме

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