当前位置: 首页 > news >正文

C++面向对象之多态的实现和应用详解

前言

本文主要给大家介绍的是关于C++面向对象之多态的实现和应用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

多态

大家应该都听过C++三大特性之一多态,那么什么多态呢?多态有什么用?通俗一点来讲->

多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。当多态应用形参类型的时候,可以接受更多的类型。当多态用于返回值类型的时候,可以返回更多类型的数据。多态可以让你的代码拥有更好的扩展性。

多态分两种分别为静态多态和动态多态:

  • 静态多态:静态多态就是重载,因为是在编译期决议确定,所以称为静态多态。
  • 动态多态:动态多态就是通过继承重写基类的虚函数实现的多态,因为是在运行时决议确定,所以称为动态多态。

而我们主要今天来看动态多态的问题。比如我们来看下面的代码,就是简单的动态多态:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

classPerson

{

public:

virtualvoidBuyTickets()

{

cout <<" 买票"<< endl;

}

protected:

string _name;// 姓名

};

classStudent :publicPerson

{

public:

virtualvoidBuyTickets()

{

cout <<" 买票-半价 "<< endl;

}

protected:

int_num;//学号

};

voidFun(Person& p)

{

p.BuyTickets();

}

voidTest()

{

Person p;

Student s;

Fun(p);

Fun(s);

}

intmain()

{

Test();

system("pause");

return0;

}

构成多态的四大条件: (缺一不可)

1.不在同一作用域(分别在父类和子类)

2.函数名相等/参数相等/返回值相同/(协变除外)

3.基类函数必须有virtual关键字

4.访问修饰符可以不同

具体多态是如何实现的?? 这里我们先从虚函数表这个知识点讲起,每一个带有虚函数的对象都会有一个虚函数表,虚函数表里存的是函数指针,然后调用的时候,指针回去虚函数表里面访问查找。对于这个知识点我的另外一个博客很详细的讲解到,大家可以先看看这个:C++中继承与多态的基础虚函数类详解_C 语言_脚本之家

然后我们来了解一下重写是什么东西?

重写的过程

如果这块还是不理解,你可以看我专门写虚函数那片博客,仔细看一定会看懂的.

接下来多态的原理我们就明白了吧. 发生重写之后,下一次父类指针指向我调用fun()函数的时候,它调用到的就是子类的fun()函数,其实多态就是这么简单,只要理解重写就理解多态. 虚函数表是我们必须掌握的一个知识点.

通过汇编来分析多态的实现

好了,我们继续往下走,刚刚我们从虚函数表这方面,探究了多态的实现,现在我们再从汇编的角度再来看多态是如何实现的。

我们来看一段新的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

classPerson

{

public:

virtualvoidBuyTickets()

{

cout <<" 买票"<< endl;

}

protected:

string _name;// 姓名

};

classStudent :publicPerson

{

public:

virtualvoidBuyTickets()

{

cout <<" 买票-半价 "<< endl;

}

protected:

int_num;//学号

};

voidFun(Person& p)

{

p.BuyTickets();

}

voidTest()

{

Person p;

Student q;

Person* ptr = &q;

p.BuyTickets();

ptr->BuyTickets();

}

intmain()

{

Test();

system("pause");

return0;

}

打开我们的反汇编窗口:

这里我们看到用指向子类的父类类型指针调用BuyTickets函数和直接用对象调用汇编代码相差巨大,一个只有2句话,一个那么长,这是因为在发生多态时当你用指针调用时,系统不知道你要用哪一个函数,因为这里有多态现象,所以系统只能老实的去虚函数表里查找,所以才会有这么多的代码,接下来我们来解释一下这些汇编,来看看系统是调用虚表的。

这里我们就关心到了那四个红色的句子,可以看到这里一直都是想讲虚函数表的地址传给系统,然后再传this指针,就可以调用哪个函数了。蓝色的就是一个小知识~ 知道有这么个东西就好了.

http://www.jsqmd.com/news/1185497/

相关文章:

  • AI编程时代,PPT已成为过去,单个HTML文件创造无限可能
  • 怎么用 Claude 做 excel 表格 避坑指南,AI 导出鸭解决表格乱码、格式丢失难题
  • Pandas多维聚合实战:用MultiIndex构建可导航数据拓扑
  • LLM大模型中的概率分形理论与优化实践
  • STM32驱动压电蜂鸣器方案与优化实践
  • 扩散模型从入门到实战:2小时掌握DDPM核心原理与PyTorch实现
  • 嘎嘎降AI工具:学术论文降AI率实战指南
  • YOLOv8实战:构建Apex游戏人物识别检测系统完整教程
  • 十二、任务管理
  • 【STM32HAL开发】学习笔记(3)——串口
  • RUST编程学习-碎片2-Unsafe
  • 2026 年通辽优秀的叉车出租订做厂家哪家强,别再自己买!效率翻倍的秘密工具解析 - 企业官方推荐【认证】
  • 【Unity3D】TrailRenderer进阶:从导弹尾焰到武器挥砍的实战特效
  • 基于YOLOv8的道路坑洼检测系统:从模型训练到PyQT5界面开发全流程
  • C++ HTTP客户端库cpr:现代化网络请求的实践指南
  • Windows平台微信QQ防撤回工具RevokeMsgPatcher原理与实战指南
  • 【项目编号:project05966】SpringBoot/Vue 电影推荐系统:用户端推荐、电影资讯与后台数据管理全流程
  • Unity URP性能优化:SRP Batcher原理、配置与实战指南
  • 反应式Agent在智能控制系统中的设计与优化
  • UE5 RPG技能系统开发:从蓝图到C++的Gameplay Ability System实战指南
  • STM32与A3908驱动的高精度运动控制系统设计
  • C语言模块管理器设计与实现:从编译原理到工程实践
  • Unity 2D游戏开发入门:从基础到实战
  • C++集成学习实战:从原理到工程,掌握Bagging、Boosting与Stacking
  • LLM注意力可视化在医疗诊断中的实践与应用
  • postman 接口自动化
  • 如何解决Kimi到word的格式问题?AI 导出鸭把Markdown/LaTeX编译成docx的技术拆解
  • 【2013-11-27】《Java编程思想》读书笔记:synchronized
  • stable-diffusion.cpp:纯C/C++实现AI绘画推理,打造轻量高效的生成式AI运行时
  • 表格 deepseek 工具哪个好用无需纠结,AI 导出鸭适配全场景表格导出