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\) 为CAT、DOG或ANIMAL。用父类引用调用。NV t:speak不是虚函数。同样三种动物,用父类引用调用。NO_OVERRIDE:基类speak为虚函数,但猫类**不重写**,用父类引用指向这只猫。HAS_VFPTR:询问「写成虚函数后,类里有没有虚函数表指针」NO_VFPTR:询问「没有虚函数时,类里有没有虚函数表指针」
输出格式
每个操作一行,行末换行:
V CAT:小猫在说话V DOG:小狗在说话V ANIMAL:动物在说话NV无论哪种:动物在说话NO_OVERRIDE:动物在说话HAS_VFPTR:YESNO_VFPTR:NO
说话必须经由父类引用调用 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
- 通过率
- ?
- 上传者