虚机制

一、虚机制的引入

在这里插入图片描述

在这里插入图片描述

利用动态编联实现——虚函数来解决上述问题

在这里插入图片描述

二、虚函数

在这里插入图片描述

  • 类中只要有其他的虚函数,析构函数就应该定义成虚函数。

在这里插入图片描述

  • 若基类中析构函数为虚函数,则派生类中的析构函数不论写不写virtual关键字都是虚函数。
  • 派生类中新的虚函数应尽量避免与基类中的虚函数重名。若重名,则写不写virtual关键字都是虚函数。
  • 相同或相容:返回类型与基类相同或互为父类和子类的关系。

三、虚函数表

1、引入:
在这里插入图片描述
2、定义:
在这里插入图片描述

  • 说明中的第一点,虚函数可以是自己定义的也可以是从基类中继承的
  • 说明中的第四点,派生类中的前几个,顺序与基类中定义的函数顺序相同,然后才是派生类中自己定义的函数。

在这里插入图片描述

  • 若在基类的Show()函数前加上virtual关键字,运行结果不变
  • vptr虚拟表指针,指向虚拟表。

四、虚机制的作用机制

1、
在这里插入图片描述
需要注意的是对象型和指针、引用型不同,静态、动态一致!(本题中即为Parent类型),因为是子类向父类转化,已经过裁剪。

  • sh1静态类型为Shape类型,动态类型为矩形;psh2静态类型为Shape指针类型,动态类型为圆的指针类型。
    在这里插入图片描述
  • Func可能不被调用,因为通过虚拟表找到的未必就是Func函数。

EX1:
在这里插入图片描述

  • 标红的代码部分,需注意p1、p2的静态类型都是A类,而在A类中是找不到f1()的,因此编译报错。

EX2:
在这里插入图片描述

  • Date类析构函数加virtual关键字的原因:如果不加virtual关键字则不会采用虚机制,在delete pDate1的时候就不会调用派生类的析构函数,而是直接释放基类的析构函数。

五、虚函数的访问

在这里插入图片描述

  • 给p2发送的消息X仅限于f、g、k,因为p2的静态类型为A类,而在A类中无h函数。
  • 若给p2发送消息f,则找到B类中的f,而B中f大括号内的g()和k()全部视为this->g()/k(),其中this->g()找到A类中,g()中的k()视作this->k(),也是A类中的k(),非虚函数为静态编联。而f中的this->k()在B类中,其中的h()视作this->h(),仍在B类中,非虚函数为静态编联。

在这里插入图片描述

示例:

在这里插入图片描述

  • p->vf()时,输出Derived::vf()。

  • p->vg()时,派生类中无vg函数,所以先输出Base::vg(),而this->vf()是虚函数,因此动态编联,输出Derived::vf(),this->nvh()是非虚函数,静态编联,输出Base::nvh(),this->vf()是虚函数,因此动态编联,输出Derived::vf()

  • p->nvh()时,由于静态类型Base中nvh()为非虚函数,所以先输出Base::nvh(),而this->vf()是虚函数,采用动态编联,输出Derived::vf()

  • delete p时,由于Base类的析构函为虚函数,所以动态编联执行派生类的析构函数,执行vf(),而派生类析构之后会再析构基类,所以会再执行基类析构函数中的vf().输出Derived::vf() Base::vf()

因此本段程序的完整输出结果为:
在这里插入图片描述

六、具体类与抽象类

在这里插入图片描述

  • 抽象类示例:图形的shape类(其子类可包括圆、矩形等),动物类(其子类可包括猫、狗等)

在这里插入图片描述

  • 纯虚定义必须类外实现!

在这里插入图片描述

  • 接口类中公有的成员函数功能要求能被子类全部实现,作为公共接口的功能

七、运行时类型识别

C++语言要想使用运行时类型识别,要求类中必须有虚函数
1、
在这里插入图片描述

  • 一般通过虚机制实现,且效率较低。
  • typeid不是函数,是操作符!

2、常见于父类向其子类转化:

动态类型转换在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值