C++语法——详解虚继承

2024-06-04 4149阅读

目录

一.什么是虚继承

二.虚继承原理

三.虚继承使用注意事项


一.什么是虚继承

所谓虚继承(virtual)就是子类中只有一份间接父类的数据。该技术用于解决多继承中的父类为非虚基类时出现的数据冗余问题,即菱形继承问题。

小编用一张图来表述一下:

如果是下图这种非虚继承,那么D类中就会出现两个 int a,当我们用D实例化对象调用a时,编译会报错,因为发生了混淆。除非指定类域B或C。当然指定A也可以,因为默认会从第一个父类中找。

C++语法——详解虚继承 第1张

 此时,D的实例化对象内部结构如下:

C++语法——详解虚继承 第2张

而当我们使用虚继承时,结构是下图这样,D中只有一份父类A,当我们调用A中数据时,并不会发生冗余。

C++语法——详解虚继承 第3张

 此时,D对象内部结构是这样:

C++语法——详解虚继承 第4张

二.虚继承原理

在上图中,父类数据并不存放在虚继承的子类中,那么子类怎么找到父类数据呢?

——在虚继承的类中,会定义一个虚基表指针vbptr,指向虚基表。

而虚基表中会存在偏移量,这个量就是表的地址到父类数据地址的距离。

我们可以通过调试,找到虚基表指针和虚基表:

首先,我们为每一个数据赋值,以便观察:

C++语法——详解虚继承 第5张

 之后,调用监视,查看d对象地址和d中a数据地址:

C++语法——详解虚继承 第6张

 再通过d的地址查看内存窗口,看d中内存分布:

C++语法——详解虚继承 第7张

由此我们可以分析得到对象d及其内部父类的内存布局:

C++语法——详解虚继承 第8张

在这个我们可能会有个疑问,那这B和C中两个是什么呢?

C++语法——详解虚继承 第9张

 这就是虚基表指针!

再通过内存窗口,查看一下虚基表指针指向的地址,根据我们的了解应该就是虚基表,而其中存有偏移量:

C++语法——详解虚继承 第10张

 而偏移量,就是虚基表指针地址到父类数据地址的距离,这里以b中虚基表为例:

C++语法——详解虚继承 第11张

到这里我们就能解释一个问题:为什么bptr和cptr能够找到并不位于自己内部的变量a?

C++语法——详解虚继承 第12张

因为bptr和cptr都对d进行了切片,当各自寻找变量a时,会从自身的虚基表指针中找到虚基表,通过虚基表的偏移量找到变量a的地址,从而找到了变量a。 

画图解释就是这样:

C++语法——详解虚继承 第13张

 

三.虚继承使用注意事项

当使用虚继承的时候,需要注意,虚继承只有在多继承时才有用。也就是说如果只有一层继承关系或者是单继承都将不起作用。

因为虚继承是保证子类中只有一个间接父类,说简单一点就是虚继承只能在隔代继承中起作用。

比如下面两种情况即便虚继承也没有意义:

C++语法——详解虚继承 第14张

(1)是因为虽然虚继承产生了虚基表和指针,但是class B并没有子类,而虚继承是用以保证子类只有一个间接父类class A。当然话说回来,就算有子类、哪怕多个子类,也都体现不出虚继承,因为虚继承要求同一个子类的多个父类继承自同一个间接父类,而该例只有一个父类class B。

(2)是因为虽然class C虚继承了class B,但是class B是class A的非虚继承,那么B中就会有一份A。而class D对A是虚继承,就导致E在实例化时会存放一个对D而言公共的A。这样E中还是存放了两个A。调用变量时还是会混淆。

这样说可能还有些难懂,那换个说法,class B中没有虚基表指针,而D中有虚基表指针,当E从D调用int a时会从虚基表指针找到公共区域的A,而E从B中找只会在B的区域内找到int a。

画图表示E内部结构就是这样:

C++语法——详解虚继承 第15张

 正确的继承关系应该是当class A的子类继承时,都是虚继承,这才能保证当有像class E这样的间接子类定义时,class在其中都只会在公共区域有一份。对本例来说即class B是虚继承。

C++语法——详解虚继承 第16张

 

 

只有两种编程语言:一种是天天挨骂的,另一种是没人用的——Bjarne Stroustrup(C++之父)


如有错误,敬请斧正

 


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]