持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
前言
今天笔记的内容是:
- 虚拟继承(简称为虚继承)
什么是虚继承?
什么是虚继承?为什么要有虚继承?
首先,我们了解一下菱形继承。
如果有两个子类继承了同一个父类,此时又有一个类继承于这两个子类,那么这种继承方式我们称之为菱形继承。
如下所示:
像上面这样,
歌手类继承了人类的成员,演员类也继承了人类的成员。
这是因为歌手类和演员类都属于人类的一种。
但是当会唱歌的演员调用成员时,会产生二义性。(虽然可以用作用域符来辨别,但是看起来并不清晰)
会唱歌的演员类内部,实际上继承了人类的两份数据。
因为他多继承了歌手类和演员类,而不是直接继承了人类。但这也浪费了内存。
我们希望会唱歌的演员既能包含一份人类的数据成员和函数,又能共享歌手类和演员类的成员函数和数据成员,那么这种继承结构我们称之为虚拟继承,简称虚继承。
虚继承的实现
如何实现虚继承?
- 我们使用关键字
virtual
代码示例如下:
此时输出结果为:
可以看出,虚继承的实现就是在歌手类和演员类在继承人类时加上关键字virtual:
虚继承的内存布局
如果没有虚继承,那么Singer_player对象的内存布局如下所示:
可以看到,Singer_player对象包含一个完整的Singer,以及一个完整的Performer。
这就相当于一个Singer_player对象包含了两个Person。
这就是的编译失败,因为出现了模糊的成员sleep()函数,Singer_player对象不知道该调用哪个sleep().
因此我们使用虚继承。
下面,我们来看虚继承下Singer_player对象的内存布局:
虚继承下,我们再来使用sleep()函数时,就不会再模糊不清。
写在最后
好了,今天的笔记就到这里,欢迎大家到评论区一起讨论!