当前位置: 首页 > news >正文

门网站建设北京最新消息发布

门网站建设,北京最新消息发布,wordpress扫描,网站建设设计总结本篇要分享的内容是C中多继承的缺陷:菱形继承。 以下为本篇目录 目录 1.多继承的缺陷与解决方法 2.虚继承的底层原理 3.虚继承底层原理的设计原因 1.多继承的缺陷与解决方法 首先观察下面的图片判断它是否为多继承 这实际上是一个单继承,单继承的特…

本篇要分享的内容是C++中多继承的缺陷:菱形继承。

以下为本篇目录

目录

1.多继承的缺陷与解决方法

2.虚继承的底层原理

3.虚继承底层原理的设计原因


1.多继承的缺陷与解决方法

首先观察下面的图片判断它是否为多继承

这实际上是一个单继承,单继承的特点是一个子类只有一个直接继承的父类,即使又多层继承关系,但是只有一个直接父类,都称作单继承 

多继承的图示如下

 可以看到多继承中的子类扮演了两个角色,就相当于桃花既能开出好看的桃花,也能结果。

所以多继承的特点是一个子类有两个或以上的直接父类时称这个关系叫做多继承。

那在上图中使用多继承是没有错误的,他可以在一个类中结合多个类的特点,多继承的本身并没有错误,但是出错的往往是在一些使用场景下会有缺陷,如下图

有了多继承可能就会导致菱形继承(如上图)。

可以看到Student类和Teacher类都会继承Person中的属性,

但是此时Assistant同时又继承了Student类和Teacher类的话,Person中的属性在Assistant中就会出现两次,会有二义性。

这也是为什么java语言中没多继承用法的原因。

观察如下代码

#include<iostream>
using namespace std;
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";// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

 可以看到在报错中它有规定使用的访问限定符,也就是说它会将同样的属性及信息再继承一份,也就是同时具有两份数据信息从而导致数据冗余占用空间,

如果Person类的空间很大,那么浪费的空间会更大。

那如何解决这样的问题呢?

首先我们可以使用访问限定符解决二义性

,这样使用没有问题

其次是在出现菱形继承的玩儿法之后C++祖师爷又更新了一个关键字:virtual(虚拟)

我们只需要在被多继承的类的继承方法前加上virtual,即可使用虚继承,

#include<iostream>
using namespace std;
class Person
{
public:string _name; // 姓名
};class Student : virtual public Person
{
protected:int _num; //学号
};class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
void Test()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter";// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

使用了虚继承之后就可以调用冗余数据的属性了

 

 可以看到,使用了虚继承之后不管是Student类中的_name还是Person类中的_name都不管用了,使用a直接可以调用_name,并且所用的空间也是同一份地址空间。

这样就解决了在菱形继承中数据冗余的问题。

但是在一个庞大的项目中这样的问题语法依旧会坑害不少人,所以尽量的能少用多继承,就要少用多继承。

2.虚继承的底层原理

既然要了解菱形继承的底层原理,我们不妨设计一个简单一点的代码便于观察,代码如下

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;
}

那上面的菱形继承关系也很简单,如下图

除了观察菱形继承外,main函数中的内容对菱形继承的测试也同样重要;

我们将代码调试,并观察内存窗口。

使用D创建了对象d,在内存中观察d的地址即可。

 可以看到的是在B类存放了两个两个值,1和3

C类中也存放了两个值,2和4

D类中存放了一个值2,他与对象d中修改_d的值相同;

那这样存放数据是什么意思呢?

上面的代码没有使用虚函数,所以存放了两个值,导致了数据的二义性;

接下来我们使用虚函数,虚函数可以解决数据冗余和二义性的问题,我们继续观察内存的变化

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;
}

使用了虚函数继续观察内存模块

和上面对比我们发现,在B类中存放了两行数据:第一行为一个地址,第二行为所修改的数据;

在C类中,存放的数据与B类相似

D和A中的数据被修改为最后所修改的数据;

可以看到在B类和C类中将地址取代了第一次所存的数据,从而达到解决数据二义性的目的;

那这个存放的地址又是什么意思是呢?

 我们继续再调出一个监视内存的窗口来观察

再第二个观察内存的窗口中输入B类的地址,这时你就会发现在第二个内存表中存在一个数,这个数子就是距离最终修改a的偏移量,上图为十六进制的14

当我们将B类中的第一行存放的地址加上十六进制的14,就会得到_a最终的值,_a=0;

我们再来举出一组例子来证明不是巧合

 可以看到_a只被赋值,而B中不仅存放了_b的值,同样也存放了一个指针,指向了距离A的偏移量,也同样是将B类中第一行的地址加上指针所指的偏移量(8),就是1所在的位置。

以上就是设计的原理,虽然设计很多内存和地址的关系,但是这就是虚函数底层的实现设计。

3.虚继承底层原理的设计原因

那为什么要这么设计呢?

如以下情况

一个B类创建的指针会指向bb对象,也有可能指向d对象,

所以我们无法得知这个指针所指向的对象,就只能靠指针来检查另一块内存上所存放的偏移量,通过计算偏移量来计算虚继承中二义性的变量。

以上就是菱形继承的设计缺陷以及后序的设计的解决思路,以及解决思路的底层设计。

其实多继承本身没有问题,只是菱形继承的用法让多继承成为了大坑。

即使本人水平有限,尽管不遗余力但本篇对虚继承的探索仍有不足,还请读者指正,感谢您的阅读。

http://www.yayakq.cn/news/354153/

相关文章:

  • 山东泰安人才网百度网站优化排名
  • visual c 网站开发京东网站建设步骤
  • 怎么自己建设公司网站wordpress固定链接打不开
  • 大桥石化集团网站谁做的什么是网络营销网络营销的特点有哪些
  • 建站点怎么做网站seo宣传
  • 维度 网站建设网上全网推广
  • 开一家网络公司做网站前景如何漳州网站设计
  • 莘庄做网站网络营销是怎么发展的
  • 专门做眼镜的网站选择建设网站公司要注意什么问题
  • 注册好了域名怎么开始做网站如何做网络营销推广
  • 卓越 网站做外贸网站怎么访问外国网站
  • 济南网站制作公司哪家技术好内网代理ip建设网站
  • 免费建设网站公司哪家好网站首页页脚
  • 济南免费做网站设计师培训班
  • 企业网站傻瓜搭建跨境电商购物网站
  • 平湖网站制作申请完域名如何建网站
  • 广州云脑网站建设win8导航网站模板
  • 淘宝客优惠券网站怎么做专业简历制作网站有哪些
  • 小网站做几个关键词怎么样自己建立一个网站
  • 国内优秀个人网站淄博网站开发网泰好
  • 空间主机 建网站互联网发展趋势分析
  • 可以做网站头像的图片深圳做网站哪家专业
  • 网站描述多个词怎么分隔地产网站怎么做
  • 品牌网站建设特色大蝌蚪网推公司
  • 手机网站菜单栏怎么做工作邮箱认证提额
  • 五合一免费建站wordpress wp_get_post_tags
  • 北海建设网站wordpress调用文章自定义字段
  • 连云港公司网站制作深圳seo优化信
  • 网站活动推广方案wordpress前端上传大文件大小
  • 天津小型企业网站设计泗洪网页定制