C++ 菱形继承和虚拟菱形继承

菱形继承

1. 概念

菱形继承是多继承的一个特殊情况,多继承是指一个子类类继承了两个或以上的直接父类,而菱形继承问题的产生是因为该子类的父类,继承了同一个父类,注意是父类而不是直接父类。下面这张图就是直接父类,因为形状像一个菱形就称为菱形继承,但如果不是直接父类,这个形状就不是菱形了,但还是菱形继承。
在这里插入图片描述

2. 产生的问题

那菱形继承会导致什么问题呢?由图可以很容易看出,这样会导致D对象有两份A,会产生数据冗余和二义性的问题。
在这里插入图片描述
我们通过代码看看A是不是有两份

class A
{
   
protected:
	int _a;
};

class B :public A
{
   
protected:
	int _b;
};

class C : public A
{
   
protected:
	int _c;
};

class D : public B, public C
{
   
protected:
	int _d;
};

int main()
{
   
	D d;
	cout << sizeof(d);
	return 0;
}

在这里插入图片描述
再看看是不是有二义性问题

class A
{
   
public:
	int _a;
};

class B :public A
{
   
protected:
	int _b;
};

class C : public A
{
   
protected:
	int _c;
};

class D : public B, public C
{
   
protected:
	int _d;
};

int main()
{
   
	D d;
	cout << d._a;
	return 0;
}

在这里插入图片描述
下面的虚拟菱形继承可以解决这些问题。

虚拟菱形继承

1.1 使用

使用非常的简单,我们只需要在继承的时候加上virtual关键字就行了,但要注意的是virtual只需要加在会产生两份的继承位置,比如B、C都继承A,这就需要加上virtual关键字,而D继承B、C就不需要用关键字。

class A
{
   
public:
	int _a = 1;
};

class B :virtual public A
{
   
protected:
	int _b = 2;
};

class C :virtual public A
{
   
protected:
	int _c = 3;
};

class D : public B, public C
{
   
protected:
	int _d = 4;
};

int main()
{
   
	D d;
	cout << d._a;
	return 0;
}

在这里插入图片描述

1.2 原理

我们可以通过成员对象模型来研究原理。
我们通过内存窗口先来看一下没有虚拟继承的菱形继承对象模型
在这里插入图片描述
很明显的可以看到A有两份,造成了数据冗余和二义性,我们在来看一下虚拟继承以后的对象模型。
在这里插入图片描述
可以看到A只有一份,成功的解决了问题,但又产生了一个新问题,A不在B和C里,那B和C如何找到A呢?看上面的模型,细心的同学会发现B和C多了一个东西,那个东西就是解决这个问题的关键,叫做虚基表指针,指向的是一个虚基表,表里面存放的是偏移量,通过这个偏移量找到A

相关推荐

  1. C++——虚继承菱形继承

    2024-02-01 08:12:04       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-01 08:12:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-01 08:12:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-01 08:12:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-01 08:12:04       20 阅读

热门阅读

  1. C++ 结构体的构造函数

    2024-02-01 08:12:04       33 阅读
  2. 面阵相机拍摄运动的物体怎样保证图像清晰

    2024-02-01 08:12:04       41 阅读
  3. TensorFlow2实战-系列教程14:Resnet实战2

    2024-02-01 08:12:04       44 阅读
  4. 3D Gaussian Splatting-实时辐射场渲染技术

    2024-02-01 08:12:04       34 阅读
  5. TensorFlow2实战-系列教程15:Resnet实战3

    2024-02-01 08:12:04       39 阅读
  6. CSS 中的 :is(), :where(), 和 :has() 选择器简介

    2024-02-01 08:12:04       33 阅读
  7. 使用certbot申请https通配符证书【阿里云篇】

    2024-02-01 08:12:04       38 阅读
  8. K8S网络

    K8S网络

    2024-02-01 08:12:04      33 阅读
  9. k8s学习-数据管理

    2024-02-01 08:12:04       29 阅读
  10. brpc之单例

    2024-02-01 08:12:04       33 阅读
  11. Qt之connect函数使用

    2024-02-01 08:12:04       30 阅读
  12. 原型和继承

    2024-02-01 08:12:04       33 阅读
  13. electron从入门到打包exe

    2024-02-01 08:12:04       44 阅读