为什么成员函数地址相同 [英] Why the member function address is the same

查看:96
本文介绍了为什么成员函数地址相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨〜我是一个对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆