【C++学习笔记】----详解菱形继承(虚拟继承)

1.菱形的相关问题

1.什么是菱形继承?
菱形继承是C++继承中的多继承出现的问题。

2.菱形继承带来什么问题,如何解决?
带来数据二义性,和数据冗余问题。
二义性可以通过作用域限定符,限定所操作的数据对象。
数据冗余问题,需要通过虚拟继承来解决。
图解:
在这里插入图片描述
3.什么是组合,什么是继承,适用情况有哪些?
组合和继承都是面向对象编程代码复用的方式。

组合是解决has-a的问题,(车有发动机)。
优点:封装性没有被破坏,类与类的耦合度低。
缺点:调用的时候是通过对象访问调用接口,不能直接使用接口。

继承是解决Is-a的问题,(人,学生,老师)
优点:子类直接继承父类的接口,创建对象时不用创建父类对象。
缺点:父类与子类的耦合度增加,破坏了封装性,不利于程序的维护。

2.代码展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class per
{
public:
	int _num1;
	
};

class stu:virtual public per
{
public:
	int _num2;
};

class teach :virtual  public per
{
public:
	int _num3;

};
class ass : public teach,  public stu
{
public:
	int _num4;
};
void test6()
{
	per p;
	p._num1 = 1;
	cout << p._num1 << endl;
	stu s;
	s._num1 = 21, s._num2 = 22;
	cout << s._num1 <<" "<< s._num2 << endl;
	teach t;
	t._num1 = 31, t._num3 = 33;
	cout << t._num1 << " " << t._num3 << endl;
	ass a;
	a._num1 = 41, a._num2 = 42, a._num3 = 43, a._num4 = 44;
	a.stu::_num1 = 411, a.teach::_num1 = 4111;
	cout <<a._num1 << " " << a._num2 << " " << a._num3 << " " << a._num4 << endl;
	cout << t._num1 << " " << t._num3 << endl;
	//printf("%p", *(int*)&a);
}
int main()
{
	test6();
	system("pause");
	return 0;
}

3.结果展示

在这里插入图片描述

4.结果分析

在这里插入图片描述
通过查看地址的方式,我发现虚拟继承virtual继承,子类继承父类的时候,增加了一个虚基表指针,指向虚基表,虚基表的位置存储的是00000000,下一个位置存储的是偏移量,即虚基表指针到数据的位置,结尾一般是00000000,而且它们共用一个虚基表。重复的冗余的数据,放在数据的末尾。
虚基表在内存中放在数据段,下面通过查看地址发现两个位置非常近。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值