Click here to Skip to main content
15,919,893 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi~ I am a student with very little exprience with C++.
Both printf() give me the same address when I run the following code (Compiled with Visual Studio 2010). I just can't understand why different member function can have the same address. Did I make any mistake?

C++
#include "stdafx.h"

class Base1
{
public:
	virtual void f() { }
};

class Base2
{
public:
	virtual void g() { }
};

class Sub : public Base1, public Base2
{
public:
	virtual void f() { cout<<"I am f()"<<endl; }
	virtual void g() { cout<<"I am g()"<<endl; }
};

int _tmain(int argc, _TCHAR* argv[])
{
	printf("0x%x\n",&Sub::f);
	printf("0x%x\n",&Sub::g);
        system("pause");
	return 0;
}
Posted

1 solution

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:
C++
Sub s;
s.f();
s.g();


With this:
C++
void CallVirtualFunc(void (*func)()) {
	func();
}

Sub s;
//Imagine we get the correct address for the following because they are'nt virtual functions
CallVirtualFunction(&Sub::f);
CallVirtualFunction(&Sub::g);


Then what you are getting is the address of the function CallVirtualFunc
 
Share this answer
 
Comments
UMayLaugh 26-Oct-11 3:06am    
Thanks! A good explaination that makes me get the concept easily.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900