从汇编角度来看动态绑定的概念,以及虚函数在多态中的的作用

#include "iostream"
using namespace std;
class A    // 4+4 = 8  
{
public:
	int a;
	virtual void p0() {}
	virtual void p() { cout << "A" << endl; }
};
class B : public A 
{
public:
	void p() { cout << "B" << endl; }
};
int main()
{
	A * b = new B;
	b->p();
	delete b;
	return 0;
}

看一下汇编

	A * b = new B;
008B5D48  push        8  
008B5D4A  call        operator new (08B13B1h)  
008B5D4F  add         esp,4  
008B5D52  mov         dword ptr [ebp-0D4h],eax  
008B5D58  cmp         dword ptr [ebp-0D4h],0  
008B5D5F  je          main+54h (08B5D74h)  
008B5D61  mov         ecx,dword ptr [ebp-0D4h]  
008B5D67  call        B::B (08B14BAh)  
008B5D6C  mov         dword ptr [ebp-0E8h],eax  
008B5D72  jmp         main+5Eh (08B5D7Eh)  
008B5D74  mov         dword ptr [ebp-0E8h],0  
008B5D7E  mov         eax,dword ptr [ebp-0E8h]  
008B5D84  mov         dword ptr [b],eax  // 将子类对象的内存入口赋给b指针
	b->p();
008B5D87  mov         eax,dword ptr [b]  
008B5D8A  mov         edx,dword ptr [eax]  
008B5D8C  mov         esi,esp  
008B5D8E  mov         ecx,dword ptr [b]  
008B5D91  mov         eax,dword ptr [edx+4]  // 取出虚函数表中的函数地址
008B5D94  call        eax  
008B5D96  cmp         esi,esp  
008B5D98  call        __RTC_CheckEsp (08B12E9h)  

思路很清晰,子类对象通过访问属于自己的虚函数表来调用子类方法

如果不用虚函数呢?

#include "iostream"
using namespace std;
class A    // 4+4 = 8  
{
public:
	int a;
	virtual void p0() {}
	void p() { cout << "A" << endl; }
};
class B : public A 
{
public:
	void p() { cout << "B" << endl; }
};
int main()
{
	A * b = new B;
	b->p();
	delete b;
	return 0;
}

反汇编:

	b->p();
00DF2207  mov         ecx,dword ptr [b]  
00DF220A  call        A::p (0DF14E2h)  

可以看到,如果不是虚函数,对象调用自己的方法在编译期间就已经确定了,对于A *a = new B这种,普通的调用方法在编译期间是直接替换为A::p的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值