【C++】虚函数,静态绑定和动态绑定

理论知识

覆盖:
基类和派生类的方法,返回值、函数名以及参数列表都相同,而且基类的方法是虚函数,
那么派生类的方法就自动处理成虚函数,它们之间成为覆盖关系

一个类添加了虚函数,对这个类有什么影响
总结一:
一个类里面定义了虚函数,那么编译阶段,编译器给这个类类型产生一个唯一的vftable虚函数
,虚函数表中主要存储的内容就是RTTI指针虚函数的地址。当程序运行时,每一张虚函数表
都会加载到内存的.rodata区。

总结二:
一个类里面定义了虚函数,那么这个类定义的对象,其运行时,内存中开始部分,多存储一个
vfptr虚函数指针,指向相应类型的虚函数表vftable。一个类型定义的n个对象,它们的额vfptr
指向的都是同一张虚函数表

总结三:
一个类里面虚函数的个数,不影响对象内存大小(vfptr),影响的是虚函数表的大小

 

实践知识

我们在vs下编写一下代码

class Base
{
public:
	Base(int data = 5) :mbase(data) { }
	virtual void show() { cout << "Base::show()" << endl; }
	virtual void show(int) {
		cout << "Base::show(int)" << endl;
	}
private:
	int mbase;
};
class Derived :public Base
{
public:
	Derived(int data = 10) :Base(data), mderived(data) {  }
	void show() { cout << "Derived::show()" << endl; }
private:
	int mderived;
};

我们在Base基类中定义俩个虚函数,在派生类中使用重写show方法覆盖了Base基类中的show方法。

如图:

我们在打开vs的命令提示符

输入命令:

cl 源.cpp /d1reportSingleClassLayoutBase

 

可以查看类的内存分布情况

上图为Base基类的内存分布。可见于文章理论知识说的对应起来了。


接着上例中,我们写如下代码

int main()
{
        Derived d(50);
	Base *pd = &d;

	pd->show();
}

 pb->Base Base::show 如果发现show是普通函数,就进行静态绑定

相关反汇编的代码:
                                            call        Base::show (0126143Dh)
    pb->Base Base::show 如果发现show是虚函数,就进行动态绑定了

相关反汇编的代码:

  mov         eax,dword ptr [pd]
  mov         edx,dword ptr [eax]
  mov         esi,esp
  mov         ecx,dword ptr [pd]
  mov         eax,dword ptr [edx+4]
  call           eax

显然,寄存器中的值只有在运行的时候可以确定,故称之为动态绑定。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值