C++多态的基本概念

本文探讨了C++中的静态多态和动态多态,重点讲解了动态多态的实现机制。通过实例展示了动态多态如何在运行时实现函数调用的灵活性。动态多态主要依赖于虚函数和类的继承,使得父类指针或引用可以调用子类重写的函数。这种晚绑定特性使得代码具有更好的扩展性和适应性。文章还通过内存布局分析解释了虚函数表(vftable)在多态中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态分为静态多态和动态多态,但是我们所指的多态一般都是动态多态

静态多态体现在函数重载和运算符重载

动态多态体现在派生类和虚函数运行时多态

静态多态和动态多态的区别在于静态多态的函数和动态多态的函数地址绑定时间不同,

静态多态函数地址在编译时就已经早绑定,动态多态函数的地址在运行时才绑定,所以动态多态的函数实现更为灵活。

下面是动态多态的使用例子

动物类

class Animal
{
public:

	virtual void Speak()
	{
		cout << "动物在说话" << endl;
	}
};

//猫类
class Cat : public Animal
{
public:
	
	//重写
	//函数返回值类型 函数名 参数列表 完全相同  子类的virtual可写可不写
	virtual void Speak()
	{
		cout << "小猫在说话" << endl;
	}
};

//狗类
class Dog :public Animal
{
public:

	void Speak()
	{
		cout << "小狗在说话" << endl;
	}
};

void DoSpeak(Animal &animal) // Animal &animal = cat C++中允许父子之间的类型转换 并且不需要做强制类型转换 父类的指针或者引用可以直接指向子类对象
{
	animal.Speak();
}

void Test1()
{
	Cat cat;
	DoSpeak(cat);

	Dog dog;
	DoSpeak(dog);
}

调用Test1函数,会分别输出小猫在说话和小狗在说话,这就是动态多态的好处,地址晚绑定,可以更灵活的输出自己想要的结果。

但是为什么会有这样的功能呢?

我们可以利用开发人员命令框来看一下这三个类的底层框架

Animal类:

 可以看出Animal类size的大小为4个字节,如果Speak函数没有设置为虚函数,我们可以得知,Animal类的size大小应该为1个字节,那么现在为4个字节是因为在Animal类中存储了一个vfptr,也就是虚函数(表)指针,这个指针指向了vftable(虚函数表),这个表中存放着&Animal::Speak,Animal类中Speak函数的地址。

Cat类:

 Cat类中继承了基类Animal类中的vfptr,如果我们没有重写Cat中的虚函数,那么他会继承基类的vfptr,所以我们之后调用的时候就会调用父类中的Speak函数,但是重写了虚函数后,vftable中将父类的Speak函数地址修改为Cat类的Speka函数地址,所以我们之后调用时就调用了Cat中的Speak函数,Dog类同理。所以动态多态实现了地址的晚绑定,可以更加灵活的调用我们的函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值