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

C++——多态——应试重点


在这里插入图片描述

❀保持低旋律节奏->个人主页

专栏链接:《C++学习》、《Linux学习》

请添加图片描述

文章目录

    • 一、初始多态
        • 1.1多态的介绍
        • 1.2虚函数
        • 2.1多态的实现
        • 3.1深剖多态实实现过程
        • 3.2难题剖析
    • ❀二、析构函数的重写
    • 三、关于多态的补充
        • 3.1关键字override和final
        • ❀3.2重载、重写、隐藏对比
        • 3.3协变

一、初始多态

1.1多态的介绍

多态分为静多态和动多态。

静态多态也叫做编译时多态,像之前的函数重载、函数模板就是静多态。之所以叫静多态是因为实参传给形参的这个过程在编译的时候就已经完成。静多态通过传递不同的参数就可以调用不同的函数。
ex:我传入一只猫就会构造猫叫的函数,但不会输出喵喵喵,传入一只狗就会构造狗叫的函数,但不会输出汪汪汪。

动多态主要是为了完成某个函数行为,传入不同的对象就会完成不同的行为
ex:函数为叫声,我传入一个猫就是喵喵喵,我传入一个狗就是汪汪汪。

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

在这里插入图片描述

1.2虚函数

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

class Person 
{
public:virtual void BuyTicket() { cout << "买票-全价" << endl;}
};
2.1多态的实现

多态实现需要两个条件

1.虚函数的形参必须是基类指针或者引用 调用
2.被调用的必须是虚函数,虚函数已经完成重写/覆盖

重写覆盖的条件——三同

1.函数类型必须相同
2.形参类型和个数必须相同
3.返回类型必须相同
在这里插入图片描述

代码实现

//1.9多态实现2
#include<iostream>
using namespace std;//基类
class Animal
{
public://1.重写/覆盖构建virtual void talk(){cout << "~~~" << endl;}
};//派生类一、
class dog:public Animal
{
public:virtual void talk(){cout << "汪汪汪" << endl;}
};
//派生类二、
class cat:public Animal
{
public:virtual void talk(){cout << "喵喵喵" << endl;}
};//调用基类的&或*
void Func(Animal&p)
{p.talk();
}int main()
{//由p指向的对象决定cat c1;Func(c1);dog d1;Func(d1);return 0;
}

买票

//1.9
#include<iostream>
using namespace std;class Person
{
public:
//必须构成函数重写/覆盖virtual void buyticket(){cout << "买票全价" << endl;}
};class Student :public Person
{
public:void buyticket(){cout << "买票半价" << endl;}
};//参数必须是基类& 或者*
void Func(Person& p1)
{p1.buyticket();
}void Test()
{Student s1;Func(s1);Person s2;Func(s2);
}int main()
{Test();return 0;
}
3.1深剖多态实实现过程

1.继承构成
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.实现条件二、被调用的必须是虚函数,并完成重写/覆盖
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.实现条件一、虚函数必须是基类指针或者引用调用
实现条件一是固定写法,类型必须是基类
在这里插入图片描述
4.重难理解调用谁和传入的对象有关,我定义一个cat类型传入c1 那么调用cat类
我定义一个dog类型传入d1,那么调用dog类
在这里插入图片描述

3.2难题剖析
以下程序输出结果是什么()
A:A->0 B:B->1 C:A->1 D:B->0 E:编译出错F:以上都不正确
#include<iostream>
using namespace std;class A
{
public:virtual void func(int val = 1)
{cout << "A->" << val << endl;
}virtual void test() { func(); }
};
class B:public A
{void func(int val = 0){cout << "B->" << val << endl;
}
};int main()
{B* p = new B;p->test();return 0;
}

图解
在这里插入图片描述
正确答案为B

小结

1.多态调用时,父类函数名+子类实现
2.普通调用看类型,多态调用看传入的类型是什么(指向的对象)

❀二、析构函数的重写

当基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual,都与基类函数构成重写。

虽然基类与派⽣类析构函数名字不同看起来不符合重写的规则,实际上编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统⼀处理成destructor

所以基类的析构函数加了vialtual修饰,派⽣类的析构函数就构成重写。

#include<iostream>
using namespace std;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;
}

若去掉virtual 变为~A()
在这里插入图片描述

在这里插入图片描述

小结
当基类指针指向派生类对象时,若基类析构不是虚函数,delete 会仅调用基类析构,导致派生类中动态分配的资源(如堆内存)无法释放,造成内存泄漏。

因为 析构函数名本质上是相同的都是 destructor

三、关于多态的补充

3.1关键字override和final

override是一个检查函数名的关键字,final是一个不构成多态的关键字。final加在基类函数中。
本质上override和final都是限制类的关键字

例如在下述代码中加上override可以检查出函数是否出现拼写错误

class Car {public:virtual void Dirve(){}
};class Benz :public Car {public:virtual void Drive() override { cout << "Benz-舒适" << endl; }
};int main()
{return 0;
}

再例如下述代码中加上final就不再构成多态

class Car{public:virtual void Drive() final {}
};class Benz :public Car
{public:virtual void Drive() { cout << "Benz-舒适" << endl; }
};int main()
{return 0;
❀3.2重载、重写、隐藏对比

在这里插入图片描述

3.3协变

派⽣类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引⽤,派⽣类虚函数返回派⽣类对象的指针或者引⽤时,称为协变。协变的实际意义并不⼤,所以我们了解⼀下即可。

#include<iostream>
using namespace std;class A {};class B : public A {};class Person {public:virtual A* BuyTicket(){cout << "买票-全价" << endl;return nullptr;}
};class Student : public Person {public:virtual B* BuyTicket(){cout << "买票-打折" << endl;return nullptr;}
};void Func(Person* ptr)
{ptr->BuyTicket();
}int main()
{Person ps;Student st;Func(&ps);Func(&st);return 0;
}
http://www.dtcms.com/a/525915.html

相关文章:

  • 中国建筑网建设通网站怎么建网站卖产品
  • 用phpstrom 调试 webman
  • 杭州自助建站软件网页设计素材网站有哪些
  • 网站建设设计公司类网站织梦模板(带手机端)嘉兴市城乡规划建设局网站
  • 苏州网站制作出名 乐云践新商务网站开发综合实训
  • 品牌餐饮加盟网站建设整体vi设计公司
  • 个人怎样申请网站宁波网页设计
  • 南京网站定制wordpress和帝国
  • DTD 元素:XML 与 SGML 文档结构解析指南
  • 云建站系统前三名石家庄最新数据消息
  • LLM 论文精读(十二)DeepSeek-OCR: Contexts Optical Compression
  • 软件生命周期与开发模型全解析
  • 电子商务网站有哪几种只做自己网站
  • 以下几个方面可以获取淘宝商品评论 API 数据
  • 人工智能网站应怎么做企业营销策划案例分析
  • 找考卷做要去哪个网站互联网最好的公司
  • 谷歌地图网站代码电子商务网站开发技术路线
  • 外贸网站模板推荐中国城乡住建部建设部网站
  • 2026版基于python大数据的电影分析可视化系统
  • 2025MathorCup大数据竞赛B题思路模型详细分析:物流理赔风险识别及服务升级问题
  • 有免费做推广的网站吗在线培训课程
  • PSMA-FAPI,前列腺特异性膜抗原-成纤维活化蛋白抑制剂偶联分子-相关资料
  • 蓝桥杯2020年第十一届省赛真题-作物杂交
  • 广西城市建设学校手机官方网站缩短链接网站
  • 【一文了解】八大排序-冒泡排序、选择排序
  • 【电脑软件】视频画质视频修复工具v3.0(支持GPU加速)
  • 违法网站怎么做安全网站建设方案报价表
  • 网站建设logo显示怎么设置网站是做响应式还是自适应的好
  • 网站建设中静态页面模板购物类型网站建设
  • h5可以来做网站吗寓意好的商贸公司名字