为什么成员函数地址相同 [英] Why the member function address is the same
问题描述
嗨〜我是一个对C ++很少了解的学生.
当我运行以下代码(与Visual Studio 2010一起编译)时,两个printf()都给我相同的地址.我只是不明白为什么不同的成员函数可以具有相同的地址.我犯错了吗?
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?
#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;
}
推荐答案
这里的问题是它们是虚拟的.这意味着功能地址按实例存储在虚拟表中.
可以从每个实例的vtable中获取此信息,但这非常不稳定.我不确定为什么编译器不会直接给您访问此地址.
因为您也是从2个虚拟类继承,所以也应该使用虚拟继承.class Sub : public virtual Base1, public virtual Base2
如果您不知道,这是如何调用虚拟函数的说明:
虚函数的调用方式与普通函数不同.如果转到反汇编窗口,然后转到它标识为两个函数的地址,您将看到此信息.
输出:
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]
那么这是什么意思?这意味着每次调用虚拟函数时都会调用相同的函数,并且虚拟函数的地址存储在作为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;
//Imagine we get the correct address for the following because they are'nt virtual functions
CallVirtualFunction(&Sub::f);
CallVirtualFunction(&Sub::g);
然后您得到的是函数CallVirtualFunc
Then what you are getting is the address of the function CallVirtualFunc
这篇关于为什么成员函数地址相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!