C++继承中大坑之菱形继承

             本文编号:240327

  今天我来给大家详细讲解一下关于C++之父本贾尼先生,挖下的小坑。关于继承中菱形继承的讲解。

在讲解菱形继承之前我先来给大家讲解一下,继承种类。其实分为以下两种。

第一:单继承

顾名思义:单继承指的是一个子类只有一个直接父类。

第二:多继承

顾名思义:多继承是指一个子类有多个父类

其中菱形继承是多继承的一种特殊情况

为什么说菱形继承是祖师爷挖下的坑呢?

其中包含两个方面的问题 第一点就是代码冗余 第二点就是会产生二义性

class Person
{
public:
	string _name; // 姓名
};
class Student : public Person
{
protected:
	int _num; //学号
};
class Teacher : public Person
{
protected:
	int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};
void Test()
{
	// 这样会有二义性无法明确知道访问的是哪一个
	Assistant a;
	a._name = "peter";

}

 

这段代码清晰的展示了,为什么会存在二义性,Assistant不知到去调用哪个_name 成员

并且以上调试结果展示了代码冗余的问题,会创建两个变量占用空间,而且没达到我们想要的效果。


以上是出现的问题,那么我们该如何解决大佬给我们留下来的坑呢?
 

其实运用的就是关键字virtual 来虚继承。下面我们换一个场景来具体解释。

class A
{
public:
	int _a;
};
// class B : public A
class B : virtual public A
{
public:
	int _b;
};
// class C : public A
class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

以上代码为我们本次测试代码。这段代码在监视窗口其实看不出什么特殊效果,但是当我们打开内存窗口便会看到新天地。

在这里我们观察到了,A被放到了最下面,B对应的_b是3 C对应的_c是4,那么B、C中的另一个数字代表什么呢?

在看了B中第一个位置的地址后,神奇的发现了他是一个指针,指向的空间的下一个地址是一个偏移量,这个偏移量是B的起始地址相对于A的地址的偏移量。

这个是C中第一个位置的数字对应的地址,通过这个地址我们也找到了对用的偏移量,通过C的地址+偏移量我们可以明显的找到A。


以上是解决问题的方案,运用虚继承,形成一个虚基表。能找到对应地址,通过对应地址能找到偏移量从而找到了A的变量。

在解决了菱形继承后,让我们思考几个问题。

为什么虚继承能解决这个问题? 明显这样比原来的空间还大。

答:如果我们的A中含有多个成员变量,那么在虚继承中,存放一个指针的方式便成了节约空间成本的好方式了。

全文完。希望你们喜欢。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值