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

c++进阶之多态讲解

这篇文章和大家一起学习一下c++中的多态

多态的概念

多态的概念:通俗来讲,就是多种形态。多态分为编译时多态(静态多态)和运⾏时多态(动态多态)。

什么是静态多态

前⾯讲的函数重载和函数模板,它们传不同类型的参数就可以调用不同的函数,通过参数不同从而达到多种形态,之所以叫编译时多态,是因为它们实参传给形参的参数匹配是在编译时完成的,而编译时一般归为静态,运行时归为动态

什么是动态多态

具体点就是去完成某个⾏为(函数),可以传不同的对象就会完成不同的⾏为,就达到多种形态。

多态的定义及实现

构成条件

多态是继承关系下的类对象,去调用不同的函数,产生不同的行为。

实现多态的两个重要条件

必须指针或者引⽤调⽤虚函数

被调⽤的函数必须是虚函数。

虚函数的定义

类成员函数前⾯加virtual修饰,那么这个成员函数被称为虚函数。

上图的函数就是虚函数

虚函数的重写(覆盖)

派⽣类中有⼀个跟基类完全相同的虚函数(即派⽣类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称派⽣类的虚函数重写了基类的虚函数。

需要注意的是:在重写基类虚函数时,派⽣类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后,基类的虚函数也被继承了下来,并且在基类中依旧保持虚函数的属性),但不建议这么玩

class Person

{

public:

virtual void BuyTicket() { cout << " 买票 全价 " << endl; }

};

class Student : public Person

{

public:

virtual void BuyTicket() { cout << " 买票 打折 " << endl; }

};

void Func(Person* ptr)

{

// 这⾥可以看到虽然都是 Person 指针 Ptr 在调⽤ BuyTicket

// 但是跟 ptr 没关系,⽽是由 ptr 指向的对象决定的。

ptr->BuyTicket();

}

int main()

{

Person ps;

Student st;

Func(&ps);

Func(&st);

return 0;

}

虚函数重写的⼀些其他问题(了解)

派⽣类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引⽤,派⽣类虚函数返回派⽣类对象的指针或者引⽤时,称为协变。

总结:各自(类)虚函数返回各自(类)对象的指针或应用

析构函数的重写

基类的析构函数为虚函数,此时派⽣类析构函数只要定义,⽆论是否加virtual关键字,都与基类的析 构函数构成重写,虽然基类与派⽣类析构函数名字不同看起来不符合重写的规则,实际上编译器对析 构函数的名称做了特殊处理,编译后析构函数的名称统⼀处理成destructor,所以基类的析构函数加了 vialtual修饰,派⽣类的析构函数就构成重写。

总结:1. 基类的析构函数是虚函数

           2. 派生类析构函数与基类析构函数构成重写

override 和final关键字

C++对函数重写的要求⽐较严格,但是有些情况下由于疏忽,⽐如函数名写错参数写 错等导致⽆法构成重载,⽽这种错误在编译期间是不会报出的,只有在程序运⾏时没有得到预期结果 才来debug会得不偿失,因此C++11提供了override,可以帮助⽤⼾检测是否重写。如果我们不想让派 ⽣类重写这个虚函数,那么可以⽤final去修饰。

纯虚函数和抽象类

在虚函数的后⾯写上=0(即virtual void Drive() = 0;),则这个函数为纯虚函数,纯虚函数不需要定义实现(实现没啥意义因为要被 派⽣类重写,但是语法上可以实现),只要声明即可。包含纯虚函数的类叫做抽象类,抽象类不能实例 化出对象,如果派⽣类继承后不重写纯虚函数,那么派⽣类也是抽象类。纯虚函数某种程度上强制了 派⽣类重写虚函数,因为不重写实例化不出对象。

总结:1. 纯虚函数:在虚函数的后面加上=0即可

           2. 纯虚函数不需要定义实现,只要声明即可

           3. 抽象类:含有纯虚函数的类

           4. 抽象类不能实例化出对象

           5. 派生类继承后不重写纯虚函数,这个派生类也是抽象类

多态的原理

除了_b和_ch成员,还多⼀个__vfptr放在对象的前⾯(注意有些平台可能 会放到对象的最后⾯,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代 表function)。⼀个含有虚函数的类中都⾄少都有⼀个虚函数表指针,因为⼀个类所有虚函数的地址要 被放到这个类对象的虚函数表中,虚函数表也简称虚表。

制作不易,给个三联吧,谢谢啦


http://www.kler.cn/news/329434.html

相关文章:

  • 设计模式面试题
  • 算法宝典——二分查找算法
  • RabbitMQ的相关题
  • 每日一练:杨辉三角
  • 32、Qt读写csv文件
  • 压力测试指南-压力测试基础入门
  • HashMap为什么线程不安全?如何实现线程安全
  • Ubuntu20.04 安装汉语拼音后重启登入黑屏
  • wireshark抓包工具
  • FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
  • C#里使用protobuf的简单的例子
  • centos7-zabbix安装与使用(较全的配置)
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-30
  • Excel实现省-市-区/县级联
  • 八大排序详解
  • 【Java 类与对象】多态
  • 【微服务】组件、基础工程构建(day2)
  • MQ基础:RabbitMQ真面目
  • 学习记录:js算法(四十九):二叉树的层序遍历
  • 【AI大模型】深入Transformer架构:编码器部分的实现与解析(上)
  • JavaScript爬虫:数据抓取的艺术与实践
  • 【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第十三章 Linux连接档概念
  • 数学建模运筹优化——规划问题Python版(线性、非线性、整数、0/1)
  • 中九无科研无竞赛保研经验帖——上交软院、中科大计算机、复旦工程硕、南大工程硕、浙大软件
  • 【MySQL】逐一更新数据(字段唯一)-存储过程
  • 《安富莱嵌入式周报》第343期:雷电USB4开源示波器正式发布,卓越的模拟前端低噪便携示波器,自带100W电源的便携智能烙铁,NASA航空航天锂电池设计
  • 西电25考研 VS 24考研专业课大纲变动汇总
  • Oracle EBS中 预算编制与计划 模块的财务流程概览
  • golang web笔记-2.请求request
  • 大表性能优化的关键技术