菱形继承 虚继承

        我们由上篇博客介绍了继承的分类,并用文字解释了他们,今天我们将从它们的底层内存分布模板来进一步了解与学习。

        单继承:一个类只有一个直接父类

        单继承实例:

class A
{
public:
	int _a;
};

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

void funtest()
{
	B b;
	b._a = 2;
	b._b = 1;
	
}
int main()
{
 	funtest();
	system("pause");
	return 0;
}
我们给派生类中的数据成员赋上初值来方便我们了解派生类对象的各个数据成员在内存中的存储,如图


       多继承:一个类有两个或两个以上直接父类

       多继承实例:

class A
{
public:
	int _a;
};
class C
{
public:
	int _c;
};
class D
{
public:
	int _d;
};
class B:public A,public C,public D
{
public:
	int _b;
};

void funtest()
{
	B b;
	b._a = 1;
	b._c = 2;
	b._d = 3;
	b._b = 4;
	
}
int main()
{
 	funtest();
	system("pause");
	return 0;
}
我们给派生类中的数据成员赋上初值来方便我们了解派生类对象的各个数据成员在内存中的存储,如图


     菱形继承:(钻石继承)

      程序实例:

class A
{
public:
	int _a;
};
class C:public A
{
public:
	int _c;
};
class D:public A
{
public:
	int _d;
};
class B:public C,public D
{
public:
	int _b;
};

void funtest()
{
	B b;
	b.C::_a = 1;
	b.D::_a = 2;
	b._c = 3;
	b._d = 4;
	b._b = 5;
}
int main()
{
 	funtest();
	system("pause");
	return 0;
}
我们给派生类中的数据成员赋上初值来方便我们了解派生类对象的各个数据成员在内存中的存储,如图


由于菱形继承在访问数据成员时会产生二义性和数据冗余问题,于是我们想出了虚继承的方法。

继承时采用关键字virtual来修饰基类。

虚继承实例:

class A
{
public:
	int _a;
};

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

void funtest()
{
	B b;
	b._a = 1;
	b._b = 2;
	
}
int main()
{
 	funtest();
	system("pause");
	return 0;
}

我们给派生类中的数据成员赋上初值来方便我们了解派生类对象的各个数据成员在内存中的存储,如图


我们已经初步开始了解了虚继承,接下来有三个问题:

      问题一:虚拟继承的构造函数做了什么事情?

                 构造函数由系统自动合成,将偏移量表格的地址放入派生类对象的前4个字节。


   问题二:虚拟继承与直接继承有什么区别?

              1.将偏移量表格的地址放入派生类对象的前4个字节

              2.虚拟继承的底层实现我们可以看到,首先push了一个1,作为虚拟继承的标志

   问题三:菱形虚拟继承(解决菱形继承的二义性问题)

菱形虚拟继承实例:

class A
{
public:
	int _a;
};
class C:virtual public A
{
public:
	int _c;
};
class D:virtual public A
{
public:
	int _d;
};
class B:public C,public D
{
public:
	int _b;
};

void funtest()
{
	B b;
	b._a = 1;
	b._c = 3;
	b._d = 4;
	b._b = 5;
}
int main()
{
 	funtest();
	system("pause");
	return 0;
}
我们给派生类中的数据成员赋上初值来方便我们了解派生类对象的各个数据成员在内存中的存储

菱形虚拟继承的大小,用sizeof求字节数

得到D为24个字节,由上图的内存分布可以很容易的得出结论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值