C++ - 初识多态

本文深入探讨了面向对象编程中的多态性,包括静态多态和动态多态,强调了虚函数在实现多态中的关键作用。介绍了实现多态的条件,如虚函数的使用和继承。此外,还详细阐述了抽象类的概念,特别是纯虚函数如何规范派生类的接口。最后,解释了多态的底层实现原理,涉及虚函数表和动态绑定。
摘要由CSDN通过智能技术生成

一、什么是多态

1.我们知道,面向对象语言都具有抽象、封装、继承、多态这几大特性,当然C++也不例外。
2.对于面向对象语言,多态简单来说就是同一接口,产生不同形态
3.实现多态的目的是为了一个方法可以被不同的对象调用,从而达到代码重用。避免重复造轮子。

多态分为静多态和动多态
1.静多态:在编译的时候就确定了函数的地址,然后call就调用了。
2.动多态:首先需要取到对象的首地址,然后再解引用取到虚函数表的首地址后,再加上偏移量才能找到要调的虚函数,然后call调用。

二、实现多态的条件

1.基类中被调用的函数必须是虚函数(virtual 关键字)。
2.必须有继承,并且必须由基类对象的指针或引用虚函数。
3.派生类必须对基类中的虚函数进行重写(重写要满足函数名、返回值、参数列表都相同)

补充:

1.函数名前增加 virtual 关键字,会增加类的大小,如果有一个虚函数,类的大小就会多4个字节(32位系统),多出来的4个大小即是虚函数表指针。它指向一张虚表,虚表里存放着每个虚函数的首地址。
在这里插入图片描述
2. 用子类的地址给父类的指针赋值后,指针永远只能访问父类的那部分数据(利用多态访问到的子类的函数是父类函数被替换得到)。
3.同名隐藏:子类的 fun 函数隐藏了父类所有的同名 fun 函数,不关心函数的返回值和参数,只关心函数的名字是否相同。
在这里插入图片描述

三、抽象类

3.1 概念

在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承.

class Car
{
public:
	virtual void Drive() = 0;
};
class Benz :public Car
{
public:
	virtual void Drive()
	{
 		cout << "Benz Car" << endl;
 	}
};
int main()
{
	Car* pBenz = new Benz;
	pBenz->Drive();
	return 0;
3.2 接口继承和实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。

四、多态的实现原理

动态多态是利用虚函数实现的。在类中如果出现virtual关键字,那么这个类的大小将会多出一个指针的大小(32位4字节,64位8字节),多出来的这个指针(_vfptf)指向函数指针数组的首地址,我们称这个函数指针数组为虚函数表。
子类在继承基类时,会连同虚函数表一起继承,如果子类重写基类的虚函数,则会覆盖掉虚函数表中的函数地址,然后利用赋值兼容规则用子类给基类的指针赋值时后,利用基类指针访问某个虚函数时,就可以调用子类的方法。这就是可以调用子类对象方法的根本原因。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值