[c++]菱形继承解析

菱形继承

  • 大概示意图:

菱形继承不一定只是标准的菱形,只要形似菱形的都可以叫菱形继承。


(以下说明都是默认公有继承,public和protected成员情况下)

菱形继承会造成数据的冗余和二义性:

  • 冗余:一个Assitant对象里面有两个Person的成员(如果成员是_name,那么就会有两个_name)
  • 二义性:如果用Assitant对象取访问_name,会报错(编译器不确定访问哪一个_name)

为了处理这种情况,祖先就开发并使用了虚继承

  • 我们使用更简便的例子取讲解虚继承具体是怎么取处理的:

虚拟继承之后发现: _a 变成唯一的了,并且将_a放在了D对象组成的最下面

这时候有小伙伴就会问了,那编译器怎么取访问_a呢?而且75c和764(上图中地址的后缀)存放的又是什么呢?

  • 75c和764里面的指针就是编译器找到那个唯一_a的途径 ;75c存放的地址位置指向一个叫虚基表的东西,所以B和C中存放对应地址 的指针就叫虚基表指针;
  • 虚基表里面存放着一种叫偏移量的东西,简单来说:偏移量里面第二行存放的是,当前指针(虚基表指针 )与对象底部_a之间的地址距离。[1](#当前指针(虚基表指针)与对象底部_a之间的地址距离。1)

简图解释如下: (便于和上面相通,读者们可将A和Person视作同一个类)
到这里有同学可能就会提问:那如果A(Person)里有更多的成员变量呢?那是不是虚基表里面会存更多的偏移量?

  • 事实上并不会哦,只需要存储A类型中首个声名的成员变量的偏移量即可,找到首个后,编译器自然就会向下访问下面的成员变量。

**有同学可能会问,为什么使用虚拟继承之后,对象内占用的空间变多了? **

  • 实际上这是因为A类太小了造成的错觉,加入A类中的成员函数增加到更多个,那么再虚拟后占用就会就会清晰可见的减少:
  • 证明多个成员变量都是存在对象的底部:

  1. 75c到_a(所继承A的首个成员地址)的地址770之间差了20 (16进制下是显示的是14 ) ↩︎
相关推荐
昵称画7 小时前
交接班记录电子化:三班之间的信息不漏
开发语言·数据库·人工智能·低代码·php
“AI国潮设计-小江”7 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
传奇开心果编程8 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
code tsunami8 小时前
【无标题】
开发语言·python
春弦_8 小时前
自用算法整理二
数据结构·算法·图论
CodeGL8 小时前
10、Python基础之进程和线程
开发语言·python
hetao17338379 小时前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
TechWayfarer9 小时前
PHP漏洞被利用,怎么揪出攻击IP?
开发语言·python·tcp/ip·网络安全·php
王老师青少年编程10 小时前
2025年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
卡卡~~11 小时前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法