HM134 菱形继承与虚继承

HM134 菱形继承与虚继承

HM134 菱形继承与虚继承

来源: 第 134 集 类和对象-继承-菱形继承问题以及解决方法

难度: 入门

时间限制: 1s

空间限制: 64MB

题目描述

两个派生类继承同一个基类,再有一个类同时继承这两个派生类,这种继承叫**菱形继承**(也叫钻石继承)。典型例子:AnimalSheepTuo 继承,SheepTuo(羊驼)再同时继承羊和驼。

Animal 里有一份年龄 mAge。不做特殊处理时会出现两个问题:

  1. 二义性:羊驼从羊、驼各拿到一份 mAge,直接写 st.mAge 不明确。可以加作用域区分:st.Sheep::mAgest.Tuo::mAge,分别设成不同值。
  2. 资源浪费:一份年龄就够,却存了两份。两份还可以对不上(一个 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:普通菱形里不写作用域直接访问 mAge
  • NV_N:普通菱形里年龄数据有几份
  • V_SHEEP / V_TUO / V_DIRECT:虚继承后经羊、经驼、或直接访问
  • V_N:虚继承后年龄数据有几份

输出格式

每个询问一行,行末换行:

  • NV_SHEEP:\(a\)
  • NV_TUO:\(b\)
  • NV_DIRECTAMBIGUOUS
  • NV_N2
  • V_SHEEP V_TUO V_DIRECT:都是 \(b\)(共享后被改成的值)
  • V_N1

数值必须从对应对象的成员读出。

样例

输入 #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
通过率
?
上传者