嵌入式每日八股3.15

什么是虚拟继承?

虚拟继承是C++中一种特殊的继承方式,它用于解决继承中的“钻石继承”问题

“钻石继承”是指在继承关系中,存在多个派生类同时继承自同一个基类,而这些派生类又被另一个派生类所继承的情况。这种情况会导致同一个基类在最终的派生类中出现多次,从而产生了二义性。

为了解决这个问题,C++提供了虚拟继承。虚拟继承使用关键字“virtual”来声明继承关系,使得同一个基类在最终的派生类中只出现一次,从而消除了二义性

当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。虚基类和虚拟继承是一起使用的,其中虚基类是在虚拟继承中被声明的基类。它们的组合可以解决多重继承中的菱形继承问题。

虚拟继承的语法如下:

#include <iostream>
using namespace std;

class A{}
class B : virtual public A{};
class C : virtual public A{};
class D : public B, public C{};

int main()
{
    cout << "sizeof(A):" << sizeof A <<endl; // 1,空对象,只有一个占位
    cout << "sizeof(B):" << sizeof B <<endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(C):" << sizeof C <<endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(D):" << sizeof D <<endl; // 8,两个bptr,省去占位,不需要对齐
} 

在这个例子中,类D继承自类B和类C,而类B和类C都通过虚拟继承方式继承自类A。这样,在类D中,类A只会出现一次,从而消除了二义性。

这种方式是一种菱形继承或者钻石继承

**虚拟继承的情况下,无论基类被继承多少次,只会存在一个实体。**虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关的表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类指针被称为bptr,如上图所示。如果既存在vptr又存在bptr,某些编译器会将其优化,合并为一个指针。

虚拟继承的原理是,虚拟继承会为基类添加一个虚拟表指针(vptr),所有继承了同一个虚拟基类的派生类都共享同一个虚拟表指针。这样,当派生类调用虚拟基类的成员函数时,只会使用一份虚拟表,无论基类被继承多少次,只会存在一个实体,从而消除了二义性。

需要注意的是,虚拟继承会带来一些额外的开销,包括额外的内存开销和运行时开销。因此,在使用虚拟继承时,需要考虑这些开销对程序性能的影响。

【嵌入式八股】精华版(免费216问精华八股) https://www.nowcoder.com/creation/manager/columnDetail/0rOeJm

【嵌入式八股】一、语言篇https://www.nowcoder.com/creation/manager/columnDetail/mwQPeM

【嵌入式八股】二、计算机基础篇https://www.nowcoder.com/creation/manager/columnDetail/Mg5Lym

【嵌入式八股】三、硬件篇https://www.nowcoder.com/creation/manager/columnDetail/MRVDlM

【嵌入式八股】四、嵌入式Linux篇https://www.nowcoder.com/creation/manager/columnDetail/MQ2bb0

全部评论

相关推荐

投递美团等公司10个岗位
点赞 评论 收藏
转发
投递美团等公司10个岗位
点赞 评论 收藏
转发
1 3 评论
分享
牛客网
牛客企业服务