虚函数-实现

C++中面向对象的三大特性之一:多态,主要由虚函数支撑实现。

其表现形式可以是父类指针指向子类实例,当使用该指针调用虚函数时,程序会自动调用子类同名虚函数(如果子类有实现)。可用于不同模块之间的解耦,比较常见于各种库的接口文件(一般均提供了纯虚基类)。

1. 虚函数表的存储:

每个类的虚函数表(如果存在)统一存储于程序运行时的全局数据区,为了能够找到对应的虚函数表,每个类实例对象的内存中都会存储其虚函数表地址(一般为实例内存的首地址,由编译器决定)。因此如果类A拥有虚函数(一个或者多个),其实例的内存占用都会额外增加一个指针的大小。

如果类B不存在虚函数,则其会按默认顺序存储成员变量的值。例如以下例子:

#include <stdio.h>

struct TestClass
{
	TestClass()
	{
		value = 10;
	}
	int value;
};

int main()
{
	TestClass temp;
	printf("%d\n",*(int*)(&temp));
} 

其输出的就是temp的value值10。而如果TestClass中存在虚函数时,其值输出则为虚函数表的地址了。

2. 虚函数的调用:

当通过指针的形式调用对应类的函数时,程序会经历以下几步:

1)若函数为普通函数,直接调用对应函数,返回。

2)若函数为虚函数,则根据内存首地址存储的虚函数表地址跳转至虚函数表。

3)在虚函数表中查找对应名称的虚函数,找到后调用,返回。

在上面的步骤中,之所以未提到该指针到底指向了什么地址(父类实例?子类实例?),是因为这实际并不重要,无论其指向的是什么地址,其执行步骤均为如此。若指向了父类实例,其在2步时,自然会通过其内存首地址跳转至父类的虚函数表,相对的,若指向了子类,其跳转至的则为子类的虚函数表。(有读者可能问,若指向了一个无关类的地址呢?答案是,直接走异常流程)

而从上述步骤中可以想到的另一点是,程序在判断函数是否为虚函数时,仅能通过当前指针类型来进行判断(无其他可用信息)。所以想要达到多态的效果,虚函数必然是要在父类中声明的。而父类中不存在的虚函数也是无法通过指针形式调用的(编译阶段就已经报错了,这位大兄弟)。

3. 总结:

简单来说,C++中多态效果主要是通过在类实例内存中写入虚函数表地址,调用时根据该地址跳转并寻找对应虚函数来实现的。

 

 

 

 

 

 

 

 

奇怪的知识又增加了!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值