The issue here is that they are virtual. This means that the function addresses are stored in a virtual table on a per-instance basis.
It is possible to get this information out of the per-instance vtable, however this is very unstable. I am not sure why the compiler wont give you direct access to this address.
Because you are also inheriting from 2 virtual classes, you should also be using virtual inheritance.
class Sub : public virtual Base1, public virtual Base2
This is an explanation of how virtual functions are called, if you don't know:
Virtual functions are called in a different way to a normal function. If you go to the disassembly window and then go to the address it identifies as both functions you can see this.
Output:
0x4100a
0x4100a
Disassembly window:
Sub::`vcall'{0}':
0004100A jmp Sub::`vcall'{0}' (41120h)
[heaps of other stuff removed]
Sub::`vcall'{0}':
00041120 mov eax,dword ptr [ecx]
00041122 jmp dword ptr [eax]
So what does this mean? it means that the same function is called every time you call a virtual function, and the address of the virtual function is stored at the memory address passed in as eax.
Think of it as the compiler changing this:
Sub s;
s.f();
s.g();
With this:
void CallVirtualFunc(void (*func)()) {
func();
}
Sub s;
CallVirtualFunction(&Sub::f);
CallVirtualFunction(&Sub::g);
Then what you are getting is the address of the function
CallVirtualFunc