C++:深入理解多态

06-02 1570阅读

C++:深入理解多态

一、多态的概念

       多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。

       那究竟多态的实际价值体现在哪里呢??

1、举个例子比如说购买高铁票这个行为,如果是普通人就是原价购买,如果是学生的话就是半价购买,如果是军人的话,可以优先走绿色通道购买……

2、再举个例子比如说大数据杀熟(个人看法,不一定正确,只是为了方便解释多态)

(1)在线支付市场,如果你平时经常用微信而很少用支付宝,那么在支付宝举办一些类似领取红包的活动的时候,他可能会有相关的算法去分析你的账户信息,对于很少用支付宝的用户,可能相对来说得到的红包金额就会更大,这是为了鼓励你去使用支付宝,可能你某一天在商场购物的时候,想起来自己有个红包没用,就会放弃使用微信而转而使用支付宝。同样是扫码动作,不同的用户扫得到的不一样的红包,这也是一种多态行为。

(2)游戏抽卡相信大家也体验过,充钱充的越少的可能反而抽卡的运气会更好,这样会使得你不至于跟氪佬的差距特别大,鼓励你继续玩游戏。而充值充得多可能运气就会越不好,因为你不缺钱,同样是抽卡,不同的玩家抽卡概率不同,这也是一种多态行为。

总而言之就是,我们生活中一件事情不同的群体去做需要有不同的反馈,那这就是多态!!

 二、多态的定义和实现

2.1 构成多态的条件

首先多态现象的产生是在继承的基础上产生的。

       多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。

C++:深入理解多态

   构成多态需要以下两个条件(重点):

(1)对父类虚函数的重写->三同(函数名、参数、返回值)

(2)必须是父类的指针或者引用去调用

C++:深入理解多态

 是否构成多态的不同表现:

1、不满足多态 -- 看调用者的类型,调用这个类型的成员函数

2、满足多态 -- 看指向的对象的类型,调用这个类型的成员函数

 满足多态:

C++:深入理解多态

 不满足多态:

C++:深入理解多态

思考:你可能会有这样的疑惑->我直接用在函数体里面用if……else不也可以达到这样的效果吗??为什么非得用多态来完成呢??? 

——>答:有些场景下必须得用多态才能解决,比如父类的指针或者引用调用析构函数

C++:深入理解多态

        但是由于父类的指针或引用是可以指向子类的对象的,甚至在某些场景下子类的指针或引用也可以指向父类的对象(前提是父类的对象被子类对象给赋值过) ,如果没有发生多态的话,那么就会去看调用者的类型而不是去看指向对象的类型,从而导致指向对象没有被析构,造成内存泄露。

C++:深入理解多态

加了virtual之后,就可以解决这个问题了。

C++:深入理解多态

 综上我们可以发现,if……else并不能替代多态!!!

2.2 虚函数的重写

虚函数:即被virtual修饰的类成员函数称为虚函数

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

 虚函数重写有两个例外:

(1)协变(返回值可以不同->但是必须是父子关系的指针或者引用(其实不一定是自己的父子类,其他的父子类也行))

class Person {
public:
	virtual Person* f() { return this; }
};
class Student : public Person {
public:
	virtual Student* f() { return  this; }
};
int main()
{
	return 0;
}

返回值也可以是其他父子类的指针或者引用,也可以是协变。

class A {};
class B : public A {};
class Person {
public:
	virtual A* f() { return nullptr; }
};
class Student : public Person {
public:
	virtual B* f() { return nullptr; }
};
int main()
{
	return 0;
}

(2)子类的virtual可以省略  

        因为虚函数的重写本身就是接口继承    我把除函数体以外的全部部分都可以继承下来,然后再去重写继承父类的这个函数的实现  这样只要父类写了virtual就可以了。

       我们来看一道经典的题目

class A
{
public:
	virtual void func(int val = 1) { std::cout 
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码