HM136 虚表决定走哪段

HM136 虚表决定走哪段

HM136 虚表决定走哪段

来源: 第 136 集 类和对象-多态-多态的原理剖析

难度: 入门

时间限制: 1s

空间限制: 64MB

题目描述

动态多态的条件仍是:有继承、子类重写父类虚函数,再用父类指针或引用指向子类对象。本题要说明的是它**为什么**能晚绑定,但不要打印任何地址,也不要依赖 sizeof 的具体字节数。

没有虚函数时,类里只有普通成员函数,函数不属于对象,结构接近空类,**没有**虚函数表指针。一旦把 speak 写成 virtual,类的内部会多出一个**虚函数表指针**(vfptr,也叫虚函数指针),它指向一张**虚函数表**(vftable)。表里记下虚函数的入口。

继承时,子类会拿到这份指针,并拥有自己的虚函数表:

  • 尚未重写:子类表里仍记着基类 Animal::speak,即使父类引用指向这只猫,调用仍走「动物在说话」。
  • 已经重写:只改子类自己的表,换成 Cat::speak;**父类那张表不变**。因此父类对象仍走「动物在说话」,父类引用指向猫时才走「小猫在说话」。

运行时按**实际对象**去查它自己的虚函数表,这就是晚绑定。请用两套类把「有表 / 无表 / 未重写 / 已重写」的输出差异做出来。

输入格式

第一行一个整数 \(q\)(\(1 \le q \le 1000\))。

接下来 \(q\) 行,每行一种操作:

  • V t:基类 speak 为虚函数,且猫、狗都已重写。\(t\) 为 CATDOGANIMAL。用父类引用调用。
  • NV tspeak 不是虚函数。同样三种动物,用父类引用调用。
  • NO_OVERRIDE:基类 speak 为虚函数,但猫类**不重写**,用父类引用指向这只猫。
  • HAS_VFPTR:询问「写成虚函数后,类里有没有虚函数表指针」
  • NO_VFPTR:询问「没有虚函数时,类里有没有虚函数表指针」

输出格式

每个操作一行,行末换行:

  • V CAT小猫在说话
  • V DOG小狗在说话
  • V ANIMAL动物在说话
  • NV 无论哪种:动物在说话
  • NO_OVERRIDE动物在说话
  • HAS_VFPTRYES
  • NO_VFPTRNO

说话必须经由父类引用调用 speak,不能按单词直接打印。

样例

输入 #1

8
V CAT
V DOG
V ANIMAL
NV CAT
NV DOG
NO_OVERRIDE
HAS_VFPTR
NO_VFPTR

输出 #1

小猫在说话
小狗在说话
动物在说话
动物在说话
动物在说话
动物在说话
YES
NO

输入 #2

2
NO_OVERRIDE
V CAT

输出 #2

动物在说话
小猫在说话

说明

  • V ANIMAL 仍走基类,说明重写只覆盖子类自己的表,父类表没被改掉。
  • NO_OVERRIDE 说明:光有虚函数和继承还不够,表里还是基类入口。
  • NV 说明没有 vfptr/vftable 时只能早绑定。
  • 不要输出指针地址或 sizeof 的字节数。

信息

ID
1135
难度
(无)
分类
(无)
标签
(无)
递交数
0
已通过
0
通过率
?
上传者