Я понимаю, что виртуальные функции могут вызывать проблемы с производительностью из-за двух проблем: дополнительного дефрагментации, вызванного vtable, и невозможности компиляции встроенных функций в полиморфном коде.
Что делать, если я опускаю указатель переменной на его точный тип? Есть ли еще дополнительные расходы?
class Base { virtual void foo() = 0; };
class Derived : public Base { void foo() { /* code */} };
int main() {
Base * pbase = new Derived();
pbase->foo(); // Can't inline this and have to go through vtable
Derived * pderived = dynamic_cast<Derived *>(pbase);
pderived->foo(); // Are there any costs due to the virtual method here?
}
Моя интуиция подсказывает мне, что, поскольку я передал объект его фактическому типу, компилятор должен уметь избегать недостатков использования виртуальной функции (например, он должен иметь возможность встроить вызов метода, если он захочет). Правильно ли это?
Может ли компилятор действительно знать, что pderived имеет тип Derived после того, как я его понизил? В приведенном выше примере тривиально видеть, что pbase имеет тип Derived, но в реальном коде он может быть неизвестен во время компиляции.
Теперь, когда я написал это, я полагаю, что, поскольку класс Derived сам по себе может быть унаследован другим классом, downbing pbase на Derived-указатель фактически не обеспечивает что-либо компилятору, и поэтому он не может избежать затраты на виртуальную функцию?