С вашим существующим кодом, я бы на самом деле надеялся, что ваш компилятор оптимизирует оператор if и ваше приведение, поскольку это приводит к пессимизации кода.
С точки зрения компилятора, ваша база кода может выглядетьследующим образом:
struct A{
virtual void x();
};
struct B : A{
void x() override;
};
struct C : B{
void x() override;
};
Итак, когда is видит ваше приведение и вызов функции: static_cast<B*>(a)->x()
он все равно должен обращаться к той же виртуальной таблице, что и при вызове a->x()
, так как может существовать потенциальный классC. (Обратите внимание, что я использую static_cast, поскольку приведения в стиле c являются источниками ошибок)
Если вы хотите получить прямой вызов B, вам лучше создать метод или класс final
. Другим хорошим подходом является использование оптимизации на основе профилей, в этом случае они часто сравнивают указатели vtable.
Чтобы ответить на ваши дополнительные вопросы?
- Является ли код законным? Да, это так.
- Это жизнеспособно? Да, учитывая замечания выше.
- Насколько медленным будет dynamic_cast? Медленно, я бы посоветовал написать хороший тест для этого, однако я не знал бы, как это сделать и сделать его реалистичным.
- Это хорошая практика? Нет, это делает полиморфизм менее пригодным для использования.
- Будет ли static_cast быстрым? Да, это быстро, в данном конкретном случае никаких инструкций не требуется. Хранение указателя на B может улучшиться в определенных случаях сложного наследования по сравнению с bool. Если для этого потребуется дополнительная память, это также может привести к снижению производительности. Еще одно уменьшение может быть хорошо, если просто добавить дополнительную сборку в ваш исполняемый файл.
Мой совет, особенно если вы новичок в C ++: не делайте этого или каких-либо других ручных оптимизаций. Компиляторы могут многое сделать для вас. Каждая ручная оптимизация впоследствии требует дополнительного обслуживания, используйте эти приемы только в том случае, если у вас действительно есть проблема с производительностью.
О, и если вы хотите узнать, что это за код сборки, вы можете поэкспериментировать на проводник компилятора