c++类的成员函数的调用

我知道C++有一个虚函数列表,对象有指向虚函数列表的指针,对于有虚函数的类对象调用虚函数时通过虚函数列表里面的指针实现的。。但是对于普通的非虚函数是怎么实现调用的呢、?  是怎么找到非虚函数的入口地址?  好像类对象里面只有类的一些数据成员。。求解惑  求详细的内存层次的变化
2013-09-10 20:39 提问者采纳
程序运行时内存中有一个区域【代码区】,所有代码段都存放在这里,包括虚函数和非虚函数
普通函数调用时,直接转换成代码去区的地址,生成文件时就定了
类的虚表可以看成是类的静态数据成员,类的每个对象有个指针指向这个虚表,即为虚表指针
当虚函数调用时,就是从虚表指针找到虚表,进而找到了虚函数的地址
追问
比如:class A{ public:void f(){} };
            A a;

            a.f(); //调用f();

我知道编译时类中函数会在代码区生成,还有一个偏移量来定位什么的(这不是很懂), 但是a.f是怎么知道代码区f()函数的绝对地址的?  就是想知道运行a.f()时,内存里面发生了什么变化。
回答
1
2
3
4
5
6
class  A
{
public :
     void  f() {}
     virtual  void  g() {}
};
1
2
3
4
5
6
class  B :  public  A
{
public :
     void  h() {}
     virtual  void  g() {}
};
1
2
3
4
5
void  Test(A& a)
{
     a.f();
     a.g();
}

以上是代码

下面是Test两个函数调用的汇编代码

1
2
3
4
5
6
7
8
9
10
11
12
  a.f();
001F6FCE  mov         ecx,dword ptr [a]  
001F6FD1  call        A::f (01F1433h)  
  a.g();
001F6FD6  mov         eax,dword ptr [a]  
001F6FD9  mov         edx,dword ptr [eax]  
001F6FDB  mov         esi,esp  
001F6FDD  mov         ecx,dword ptr [a]  
001F6FE0  mov         eax,dword ptr [edx]  
001F6FE2  call        eax  
001F6FE4  cmp         esi,esp  
001F6FE6  call        __RTC_CheckEsp (01F12E9h)

由此可见,f函数直接寻址(在编译时就已经确定地址了01F1433h),而g函数通过虚指针寻址

追问
恩 很明确,但是觉得类在编译时,类里面的函数只是一个相对地址,但是在连接是才进行重定位为绝对地址,这两个过程存在一个地址修改的问题(根据什么修改的很疑惑)  这样反汇编后肯定是最后的绝对地址。。
 希望能够解惑
谢谢你了 先采纳了
提问者评价
非常感谢
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值