HM134 菱形继承与虚继承
HM134 菱形继承与虚继承
来源: 第 134 集 类和对象-继承-菱形继承问题以及解决方法
难度: 入门
时间限制: 1s
空间限制: 64MB
题目描述
两个派生类继承同一个基类,再有一个类同时继承这两个派生类,这种继承叫**菱形继承**(也叫钻石继承)。典型例子:Animal 被 Sheep、Tuo 继承,SheepTuo(羊驼)再同时继承羊和驼。
设 Animal 里有一份年龄 mAge。不做特殊处理时会出现两个问题:
- 二义性:羊驼从羊、驼各拿到一份
mAge,直接写st.mAge不明确。可以加作用域区分:st.Sheep::mAge、st.Tuo::mAge,分别设成不同值。 - 资源浪费:一份年龄就够,却存了两份。两份还可以对不上(一个 18、一个 28),说不清羊驼到底几岁。
解决办法是让羊、驼对动物做**虚继承**:在继承方式前加 virtual(例如 class Sheep : virtual public Animal)。这时最上面的 Animal 称为**虚基类**。虚继承后对象里只留一份 mAge,羊、驼、自身访问的都是同一份:先写成 18 再改成 28,再怎么访问都是 28,直接写 st.mAge 也不再二义。
底层可以理解为:中间层不再各拷一份数据,而是各带一个虚基类指针,通过虚基类表里的偏移找到那唯一一份年龄。不要用 sizeof 或指针地址答题。
请同时实现「普通菱形」和「虚继承菱形」两套类,按询问读成员。
输入格式
第一行两个整数 \(a\)、\(b\)(\(1 \le a,b \le 10^9\))。普通菱形里:Sheep::mAge 设为 \(a\),Tuo::mAge 设为 \(b\)。虚继承菱形里:先经羊写成 \(a\),再经驼改成 \(b\)。
第二行一个整数 \(q\)(\(1 \le q \le 1000\))。
接下来 \(q\) 行,每行一个单词:
NV_SHEEP/NV_TUO:普通菱形里加作用域看羊 / 驼那一份NV_DIRECT:普通菱形里不写作用域直接访问mAgeNV_N:普通菱形里年龄数据有几份V_SHEEP/V_TUO/V_DIRECT:虚继承后经羊、经驼、或直接访问V_N:虚继承后年龄数据有几份
输出格式
每个询问一行,行末换行:
NV_SHEEP:\(a\)NV_TUO:\(b\)NV_DIRECT:AMBIGUOUSNV_N:2V_SHEEPV_TUOV_DIRECT:都是 \(b\)(共享后被改成的值)V_N:1
数值必须从对应对象的成员读出。
样例
输入 #1
18 28
8
NV_SHEEP
NV_TUO
NV_DIRECT
NV_N
V_SHEEP
V_TUO
V_DIRECT
V_N
输出 #1
18
28
AMBIGUOUS
2
28
28
28
1
输入 #2
100 200
3
NV_SHEEP
V_DIRECT
V_SHEEP
输出 #2
100
200
200
说明
- 样例 #1 对应课堂上先分别写成 18 和 28,再虚继承后只剩一份、全是 28。
- 虚继承加在羊、驼继承动物时,不是加在羊驼那一层。
- 不要输出
sizeof或任何地址。
信息
- ID
- 1133
- 难度
- (无)
- 分类
- (无)
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 通过率
- ?
- 上传者