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

【C++奇遇记】C++中的进阶知识(多态(一))

🎬 博客主页:博主链接
🎥 本文由 M malloc 原创,首发于 CSDN🙉
🎄 学习专栏推荐:LeetCode刷题集 数据库专栏 初阶数据结构
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述
在这里插入图片描述

文章目录

  • 😇本章详情
  • 😇多态的前情介绍
    • 📝多态的概念
  • 😇多态的定义及实现
    • 📝多态的构成条件
    • 📝 虚函数的重写/覆盖
    • 📝析构函数的重写
  • 📃如何巩固学习
  • 📃本文小结

😇本章详情

🐤本篇文章将继续讲授C++的多态相关的知识

😇多态的前情介绍

📝多态的概念

多态(polymorphism)的概念:通俗来说,就是多种形态。


运⾏时多态,具体点就是去完成某个⾏为(函数),可以传不同的对象就会完成不同的⾏为,就达到多种形态。例如动物叫是一个行为(函数),传猫对象过去,就是喵喵,传狗对象过去就是汪汪


😇多态的定义及实现

📝多态的构成条件


多态是⼀个继承关系的下的类对象,去调⽤同⼀函数,产⽣了不同的⾏为。⽐如Student继承了Person。Person对象买票全价,Student对象优惠买票。


实现多态的两个重要条件

  1. 必须是基类的指针或者引⽤调⽤虚函数
  2. 被调⽤的函数必须是虚函数,并且完成了虚函数重写/覆盖。

说明

要实现多态效果,第一必须是基类的指针或者引用,因为只有基类的指针或引用才能既指向基类对象又指向派生类对象;第二派生类必须对基类的虚函数完成了重写/覆盖,重写或者覆盖了,基类和派生类之间才能有不同的函数,多态的不同形态效果才能达到。


📝 虚函数的重写/覆盖

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


注意:在重写基类虚函数时,派⽣类的虚函数在不加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;
}

在这里插入图片描述

在上述代码中,首先我们写了一个Person基类,里面定义了一个虚函数BuyTicket,又创建了一个学生派生类继承Person基类,并且重写了BuyTicket成员函数。此时我们想要调用试一下,于是我们写了一个Func函数,参数列表必须是基类的指针或者引用。


📝析构函数的重写

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

代码实现

class A
{
public:
	virtual ~A()
	{
		cout << "~A()" << endl;
	}
};
class B : public A {
public:
	~B()
	{
		cout << "~B()->delete:" << _p << endl;
		delete _p;
	}
protected:
	int* _p = new int[10];
};
// 只有派⽣类Student的析构函数重写了Person的析构函数,下⾯的delete对象调⽤析构函数,才能
// 构成多态,才能保证p1和p2指向的对象正确的调⽤析构函数。
int main()
{
	A* p1 = new A;
	A* p2 = new B;
	delete p1;
	delete p2;
	return 0;
}

在上述代码中,如果基类A中的析构函数,不加上virtual的话,A 和B 是不构成重写的,此时在对对象进行析构的时候是会造成内存泄露的,delete p2是只会调用A的析构函数的,这样就会导致内存泄露的原因,因为~B()在释放资源

在这里插入图片描述

📃如何巩固学习

提示:在学习的过程中,我们需要先自行进行思考,并且多去阅读一些大佬的书籍,俗话说的好,书籍是人类进步的阶梯!

📃本文小结

  1. 这只是继承中的一小部分知识,山高路远,我们下期再见啦!!!!

好啦今日的分享到这里就结束啦,我是爱你们的M malloc希望可以帮助到你们噢,最后别忘记三连啦!!

在这里插入图片描述

在这里插入图片描述

相关文章:

  • 使用MySQL时出现 Ignoring query to other database 错误
  • NO.65十六届蓝桥杯备战|基础算法-贪心推公式排序|哈夫曼编码|拼数|奶牛玩杂技|哈夫曼编码|合并果子(C++)
  • 接口自动化学习二:session自动管理cookie
  • 网络协议:TCP,UDP详细介绍
  • Windows Flip PDF Plus Corporate PDF翻页工具
  • MySQL数据库精研之旅第五期:CRUD的趣味探索(中)
  • py文件打包为exe可执行文件,涉及mysql连接失败以及找不到json文件
  • 使用PyQt5绘制水波浪形的柱状显示流量—学习QTimer+QPainterPath
  • Logo语言的区块链
  • Compose组件转换XML布局1.0
  • 基于SpringBoot的医院信息管理系统(源码+数据库)
  • 基于Python的人脸识别校园考勤系统
  • 初见TypeScript
  • 微信小程序—路由
  • Qt 入门 0 之 QtCreator 简介
  • 【微服务架构】SpringCloud Alibaba(八):Nacos 2.1.0 作为配置中心(Nacos的使用)
  • SpringAI+MCP协议 实战
  • 第六章:框架实战:构建集成向量与图谱的 RAG 应用
  • Qt的window注册表读写以及删除
  • VBA数据库解决方案第二十讲:SQL在VBA中几种常见的表达方式
  • 佛山知名网站建设公司/最近国际新闻大事20条
  • 的网站建设公司哪家好/微信怎么引流营销呢
  • 网站优化人员/小程序平台
  • 做网站的技术员/免费制作网页的网站
  • 重新设置wordpress/谷歌网站优化推广
  • python做网站源码/如何制作网页