C++虚函数实现原理探究

C++虚函数实现原理探究

概念

在面向对象编程中,多态指的是一个接口有不同的实现方式。在C++中,多态是重要的概念之一。其中虚函数表的主要作用就是为了实现多态的机制。

C++支持两种多态性:编译时多态性,运行时多态性。
a.编译时多态性:通过重载函数实现
b 运行时多态性:通过虚函数实现。

首先我们讨论下为什么需要多态概念的引入:我们设置很多小动物,猪,牛,羊等等,每个动物都有自己独特的叫声,但每个动物又都有共同的属性,比如睡觉,吃饭等等。于是我们要为每一个动物创建一个call()方法,表示不同的动物在叫,又必须为每一个动物创建eat,sleep方法,然后因为eat,sleep是属于所有动物的共同的属性,写很多遍eat,sleep内容一样的方法是无法忍受的,因此我们引入了抽象的概念,可以把各类动物都抽象为动物,每个动物又可以实现自己特有的属性call,共有属性eat,sleep。这个在C++中是怎么实现的呢?答案就在今天我们要探讨的虚函数中。我们可以创建猪,牛,羊的方法,通过动物*指向不同的实例,这样,在调用牛->吃的时候,就是调用动物这个类中的实现,而调用牛->叫的时候,我们可以直接调用牛这个类的实现。但具体我们应该怎么实现呢?这里,我们引入virtual关键词,即通过虚函数表实现。
下面我们引入一段代码:

代码示例

#include <iostream>
using namespace std;
class animal
{
public:
	virtual void say()
	{
		cout << "i am animal" << endl;
	}
	virtual void eat()
	{
		cout << "i am animal, i am eat" << endl;
	}
	virtual void sleep()
	{
		cout << "i am animal, i am sleep" << endl;
	}
};
class cattle : public animal
{
public:
	void say()
	{
		cout << "i am cattle" << endl;
	}
};
class pig : public animal
{
public:
	void say()
	{
		cout << "i am pig" << endl;
	}
};
class sheep : public animal
{
public:
	void say()
	{
		cout << "i am sheep" << endl;
	}
};
int main()
{
	cout << "virtual test" << endl;
	animal* c = new cattle;
	c->say();
	c->sleep();
	c->eat();
	animal* s = new sheep;
	s->say();
	animal* p = new pig;
	p->say();

	getchar();
	return 0;
}

输出结果:
这里,所有的指针类型都是animal类型,指向了不同的实例,所以对应的调用结果也不一样的
根据上述结果,我们分析一下,所有的指针类型都是animal类型,指向了不同的实例,所以对应的调用结果也不一样的。

分析

那具体的虚函数表在系统中是如何实现的呢?
在这里插入图片描述

在animal的实例中,保存了一个_vfptr的虚函数表,因此可以根据表中存储的函数指针,定位具体需要调用的函数,如果实例指向cattle,则animal::say()对应的单元格存储的就是cattle::say()的函数指针。
在这里插入图片描述
至此,我们明白了多态是通过虚函数表的方式实现的,并且通过上述截图,发现需要中的cattle::say(),animal::eat(),animal::sleep()均是void类型,因此,这里是通过虚函数表保存函数指针的方式实现的。因此,上述调用中,c->say();实际调用的是c->(_vfptr[0])。

对于上述例子,animal类中也有say方法的实现,但是在子类中,被覆盖了,因此在虚表中也被其覆盖了,如果子类中不对say进行实现,则需要中会指向animal::say()。我们也可以将animal的say方法作为纯虚函数进行设定,即

virtual void say() = 0;

这样,每一个子类在继承了父类animal后,都必须有自己的特化实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值