多态实现原理

**摘要:**本文围绕 C++ 多态的实现条件与底层原理展开,重点讲解虚函数重写、父类指针或引用指向子类对象这两个核心条件,并结合虚函数表与虚函数指针的机制,说明多态调用是如何被触发的。文中通过监视窗口示意图和完整演示代码,直观展示子类重写虚函数后,父类引用指向不同对象时调用对应函数的过程。

目录

一、多态实现条件

1、子类必须重写父类的虚函数

2、由父类的指针或者引用指向子类对象

二、多态的原理

1、子类必须重写父类的虚函数

2、父类的指针或者引用指向子类对象


s

一、多态实现条件

1、子类必须重写父类的虚函数

虚函数的重写由两个例外

1、协变:协变的要求是返回值可以不同,但必须是父类的指针或者引用

2、派生类重写虚函数时,可以不写 virtual,继承虚属性;写上可读性更好。

2、由父类的指针或者引用指向子类对象

原理:通过虚函数表 +虚函数指针触发多态调用条件,

包含虚函数的类都有自己的虚函数表 ,并且在对象内存中有虚函数表指针 指向自己的虚函数表,

当用父类的指针或者引用指向子类对象 时,父类的指针或者引用 通过虚函数表指针 找到子类的虚函数表,最后调用子类重写后的虚函数。

问题:为什么不能是子类的指针或者引用

多态的核心目标是:同一个调用入口(指针 / 引用),指向不同类型的对象时,能自动调用对应类型的函数

**原因是子类的指针或者引用指向子类对象时,不能指向父类时调用父类的虚函数(语法不支持,不符合继承语义),只能做到指向子类的虚函数。**而父类的指针或者引用天然可以指向父类对象,也可以指向子类对象,可以做到通过一个调用入口,指向不同对象时,能够调用对应类型的函数

二、多态的原理

1、子类重写父类的虚函数监视窗口

子类得到父类的虚函数表,重写的虚函数会覆盖父类的虚函数。如下图所示

2、父类的引用指向子类对象监视窗口

首先对象内存模型中,有指向虚函数表的指针虚函数表指针 指向虚函数表虚函数表 中存放的是虚函数的地址

当父类的引用p指向了父类对象,调用的是父类的虚函数。

当父类的引用p指向了子类对象,调用的是子类重写父类后的虚函数。

3、演示代码

复制代码
class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "票价-全价" << endl;
	}
	virtual void func1()
	{
		cout << "Person::func1()" << endl;
	}
	virtual void func2()
	{
		cout << "Person::func2()" << endl;
	}
private:
	int _a=1;
};
class Student : public Person
{
public:
	virtual void BuyTicket()
	{
		cout << "票价-半价" << endl;
	}
private:
	int _b=2;
};

void func(Person& p)
{
	p.BuyTicket();
}
int main()
{
	Person p;
	Student st;
	func(p);
	func(st);
}
相关推荐
wanglei20070819 分钟前
消息队列的协作模式
开发语言·python
jimy138 分钟前
拷贝构造时,不用引用的话,按值传参会无限递归调用拷贝构造函数
开发语言
LccKyI41 分钟前
# C# 基础编程 面试题汇总(一)
开发语言·c#
CODER03041 小时前
win11系统编译安装cuda版llama-cpp-python(踩完所有的坑)
开发语言·python·llama
神仙别闹1 小时前
基于C语言+SQLite 实现(控制台+图形界面)图书管理系统
c语言·开发语言·sqlite
水饺编程1 小时前
第5章,[Win32 章节] :绘制填充区域
c语言·c++·windows·visual studio
何以解忧,唯有..1 小时前
LangChain 模型调用方法总结:invoke、batch、stream 的入参与出参
开发语言·langchain·batch
SamChan901 小时前
Python+ReportLab自动生成PDF翻译质量审计报告:从数据到可视化的完整方案
开发语言·python·ai·pdf·wpf
深念Y1 小时前
Makefile vs go run:Go 项目构建方式对比
java·开发语言·golang·k8s·编译·流水线·cicd