多态实现原理

**摘要:**本文围绕 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);
}
相关推荐
学逆向的7 小时前
C 堆区内存管理
c语言·开发语言·网络安全
huoyueyi7 小时前
《融天AI-APP从0到1开发实录》
开发语言·lua
xiaoye-duck8 小时前
《C++ 工具库实战》gflags 命令行参数解析库详解
c++·第三方库
OpenAnolis小助手8 小时前
PHP 两个严重漏洞曝光,龙蜥社区 24 小时完成 3 版本修复
开发语言·操作系统·php·龙蜥社区
狂奔的sherry9 小时前
C++ 宏生成访问函数的代价:访问权限、调试和类型检查
c++·宏·编译·预处理器·类型检查
阿尼卡~9 小时前
VS Code 配置 C 语言开发环境(Windows 10/11):从 GCC 安装到运行、断点调试,一篇搞定
c语言·开发语言·windows
划破黑暗的第一缕曙光10 小时前
[C++]:5.STL:string(2)
java·c++·redis
hhhjhl11 小时前
Undici 跨端三方库仓颉适配全流程
java·开发语言·ubuntu
染指111011 小时前
158.Agent-LangGraph-子图(共享状态和不共享状态模式)
开发语言·人工智能·python·ui·agent·agents
wangchunyu11411 小时前
JAVA JVM内存结构与运行时数据区
java·开发语言·jvm