The C++ standard doesn't say how this should be implemented. It's up to the compiler if it does it by using multiple vtables, combines the vtables [in such a way that they can then be "split" again, because C
must be possible to make into a B
type object again].
Using multiple vtables is quite a common solution in compilers, so you will see this solution in at least MS's VC++, GNU's g++, LLVM/clang++ and ARM's armcc++. Since I don't know how it works in other compilers, I can't say if other compilers do use this method or not (quite possibly).
To be clear, it is a popular method, but the standard doesn't say how this should be done.
In the future, this may change - someone may come up with a different solution that is better (by some definition of better - e.g. takes up less space, has faster access, etc)