With your existing code, I actually would hope your compiler optimizes away the if-statement and your cast as this is pesimizing the code.
From the compiler's point of view, your code-base could be looking the following way:
struct A{
virtual void x();
};
struct B : A{
void x() override;
};
struct C : B{
void x() override;
};
So, when is sees your cast and function call: static_cast<B*>(a)->x()
it still has to access the same virtual table as to when calling a->x()
as there could be a potential class C.
(Please note that I use static_cast, as c-style casts are sources for bugs)
If you want to get a direct call to B, you better make the method or class final
. Another good approach is using profile guided optimization, in which case, they often compare the vtable pointers.
To answer your side questions?
- Is the code legal? Yes, it is.
- Is this viable? Yes, given the remarks above.
- How slow will the dynamic_cast? Slow, I would argue to write a good benchmark for this, however, I wouldn't know how to do so and make it realistic.
- Is this good practice? No, it makes the polymorphism less usable.
- Will the static_cast be fast? Yes, it's fast, in this specific case, there ain't any instructions needed. Storing a pointer to B could both improve in specific cases of complex inheritance compared to the bool. If it would take extra memory, it could cause a decrease in performance as well. Another decrease could come well by just having extra assembly in your executable.
My advice, especially since you are new to C++: Don't do this or any other manual optimizations. Compilers can do a lot for you. Every manual optimization causes extra maintenance afterward, only use these kinds of tricks if you actually have a performance problem.
Oh, and if you want to know what the actual assembly code it, you can experiment at compiler explorer