C++:多态上(虚函数)&override&final

概念

通俗来说就是多种形态;
也就是说 不同对象完成某个(同样)行为会产生不同的结果

例如: 比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;

代码实现

虚函数:被virtual修饰的类成员(不能是静态)函数

满足了两个条件才能实现多态

  • 构造条件
    继承体系下
    父类中有虚函数
    子类对父类中的虚函数进行了重写(写法:直接将方法原型拷到子类中,改写函数体)
  • 调用条件
    虚函数只能通过父类的引用或者指针调用

多态的体现:程序运行时,根据基类的指针指向不同类的对象,选择对应的虚函数进行调用
在这里插入图片描述
如果不通过父类指针或者引用调用虚函数,虚函数就是直接调用的

  • 编译过程:
    编译阶段,p.bark(),该方法不知道要调用哪个类的方法
    编译时,p到底引用的是猫还是狗,是确定不下来的,程序运行时需要传参,才能知道p指向哪个类的对象
  • 函数的调用过程:56行的注释

重写(重新写方法)

子类中有一个和父类完全相同的虚函数(函数名,返回值,参数列表),则子类虚函数重写了父类虚函数

构成重写的条件

  1. 父类函数一定要是虚函数(一定要加关键字),
    子类可以不加关键字但是最好加上;
  2. 父子类虚函数原型要一致:函数名,参数列表,返回值类型
    返回值类型(但是有规则)和函数名不同(只有一种情况)也可能构成重写
    例外:协变(返回值类型不同) 和 析构函数重写(函数名不同)
  3. 重写和在父子的权限无关

析构函数重写

将父类的析构函数设置为虚函数

  • 作用:防止因子类涉及资源管理造成内存泄漏
  • 过程分析:
    父类指针指向子类对象时会有资源泄露
    new是调用子类构造函数构造对象
    delete在析构时,调用的是父类析构函数,导致资源泄露
  • 为什么可以防止资源泄露
    父类指针指向子类对象,调用父类的析构函数,编译器发现父类析构是虚函数,则调用指针所指向对象的虚析构函数在这里插入图片描述

协变

子类和父类虚函数的返回值类型不同,可以构成重写

  • 父类虚函数返回父类的指针或者引用
  • 子类虚函数返回子类的指针或者引用

返回类型可以不是同一继承体系,如右侧代码
在这里插入图片描述

override

C++11提供的关键字
重写的最大限制条件是要保证函数原型一致
函数名不同,在编译阶段是不会报错,只能在运行时候出错

关键字作用:用于修饰子类虚函数,在编译阶段检查子类虚函数是否对父类虚函数进行重写,未重写则报错

final

修饰虚函数:表示类中的虚函数不能被其子类重写
修饰类:表面类不能再被继承

重载、重定义、重写的区别

在继承体系中,如果父类和子类两个 成员函数名相同,不是重写就是重定义

参数列表:参数个数,类型,类型次序

不能作为虚函数的函数

虚函数是为了实现多态,通过虚表进行调用

构造函数

  • 构造函数作用是为了初始化对象,给对象空间赋合适的初始值;
  • 如果构造函数可以做虚函数,那么其调用就需要在虚表中提取;
  • 但是虚表是对象构造完整之后才出现的,自相矛盾

静态成员函数

没有this指针,不能通过对象调用,没有对象就没有虚表;

友元函数

不属于类成员函数

内联函数

从语法层面上可以,被inline修饰函数会在编译阶段尽量被展开,被展开就不能实现多态,virtual关键字就没有意义了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值