Статическое связывание (early binding, компиляционное время):
void greet() { std::cout << "Hello!"; }
Динамическое связывание (late binding, run-time):
class Animal { public: virtual void speak() { std::cout << "Animal"; } }; class Dog : public Animal { public: void speak() override { std::cout << "Woof"; } }; void foo(Animal* a) { a->speak(); } // динамическое связывание
Когда использовать:
Вызовет ли применение ключевого слова override ускорение работы виртуальных функций?
Ответ:
Нет, ключевое слово override служит только для явного указания компилятору о том, что функция должна переопределять виртуальную базовую функцию. На производительность или способ вызова функций не влияет.
class A { public: virtual void func(); }; class B : public A { public: void func() override; // для проверки компилятором, но не меняет скорость вызова };
История
В высоконагруженной биржевой библиотеке команда использовала виртуальные методы для большинства операций, даже когда полиморфизм не был необходим. В результате система работала медленнее, чем планировалось — основной bottleneck был в vtable lookups.
История
В проекте с расширяемыми алгоритмами сотрудники применяли обычные методы вместо виртуальных. Позднее оказалось, что при передаче объектов через базовые указатели поведение не менялось, происходили неправильные вычисления; баги устранили, только переписав интерфейс.
История
В проекте по анализу медиа файлов разработчики путали статические и виртуальные методы. Некоторые функции для разных форматов забывали объявить виртуальными и не переопределяли в наследниках, из-за чего обработка файлов шла по неверному пути, а результаты кэшировались с ошибками.