返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >一文读懂C++中的继承之菱形继承(案例分析)
  • 844
分享到

一文读懂C++中的继承之菱形继承(案例分析)

2024-04-02 19:04:59 844人浏览 薄情痞子
摘要

目录前言一、什么是多继承?1.单继承2.多继承二、菱形继承1.虚基类的引入2.虚基表的引入总结前言 我们上一篇说了世间万物都有一个继承体制,或多或少子类继承了父类的某些特征,但大多都

前言

我们上一篇说了世间万物都有一个继承体制,或多或少子类继承了父类的某些特征,但大多都是单向继承,但是就有些特例他就是多继承,比如:

我们从图片中就可以看到,两栖动物它既继承了水生动物的一部分特性,也继承了陆地动物的一些特性,那么我们的代码,会不会也会有这种多继承现象呢,我们一起来看一下。

提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是多继承?

1.单继承

  我们来看一个图先了解一下单继承,再看有什莫区别

也就是说,一个子类只有一个直接父类时称这个继承关系为单继承

2.多继承

我们把 一个子类有两个或以上直接父类时称这个继承关系为多继承

我们看一下代码,看看多继承中存在哪些问题。


//基类A
class A 
{
public:
  A() :m_data(1)
  {
  }
  ~A(){}
 
public:
  int m_data;   //同名变量
  
};
//基类B
class B
{
public:
  B() :m_data(1)
  {
  }
  ~B(){}
 
public:
  int m_data;   //同名变量
  
};
 
class C : public A, public B
{
 
};
 
int main()
{
  C Data;
  //Data.m_data = 10;  //错误, 提示指向不明确 不能够分辨m_data到底是谁的
  //只有通过域成员运算符给其明确指出才可以访问,
  Data.A::m_data = 5; 
  Data.B::m_data =10;
  
  std::cout << Data.A::m_data << "  " << Data.B::m_data << std::endl;
 
  return 0;
}

通过上面的代码我们明显看的出,多继承体系中存在二义性问题。指如果有同名的数据成员 那么就无法直接通过变量名进行读取,需要通过域(::)成员运算符进行区分

就好像一个人说 去给老师送个东西去,那么多老师,你无法确定他所指的是哪一个老师,必须指名道姓,我们才可以区分。一个道理

二、菱形继承

我们先来画张图,理解一下什么叫做菱形继承

我们把这种继承类型叫做菱形继承。

那么这种继承体制,又会出现什么样的问题呢?我们通过下面的代码具体看一下。


// 菱形继承 菱形继承是多继承的一种特殊情况。
//菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。
 
 
class A
{
public:
	int m_a = 1;
};
class B :public A
{
public:
	int m_b = 2;
};
class C :public A
{
public:
	int m_c = 3;
};
class D :public B, public C
{
public:
	int m_d = 4;
};
void main()
{
	D d;
	d.m_d = 40;
	d.m_c = 30;
	d.m_b = 20;
	//.m_a = 10;// 二义性
	// 不能够访问 因为B 和C分别继承了A的m_a
	//但是D 继承了B和C的m_a 所以D不能够分辨m_a到底是谁的
	d.B::m_a = 100;
	d.C::m_a = 200;
	// 这样的话 就造成了m_a 有两个空间 一个B的100 一个C的200
}

我们根据上面的情况不难看出,菱形继承中也存在数据的二义性,这里的二义性是由于他们间接都有相同的基类导致的。 这种菱形继承除了带来二义性之外,还会有有数据冗余浪费内存空间

何为空间浪费,数据冗余,我们画图展示一下。

那么该怎样解决这种问题,

1.虚基类的引入

c++中引入了虚基类,其作用是 在间接继承共同基类时只保留一份基类成员。

我么看一下代码


class A
{
public:
	int m_a = 1;
};
class B :virtual public A
{
public:
	int m_b = 2;
};
class C :virtual public A
{
public:
	int m_c = 3;
};
class D :public B, public C
{
public:
	int m_d = 4;
};
void main()
{
	D d;
	d.m_d = 40;
	d.m_c = 30;
	d.m_b = 20;
	d.m_a = 100;// 让B C虚拟继承 A 加关键字virtual
}

我们可以看到很好解决了二义性和数据冗余的问题,那么它是具体怎么来做的,

2.虚基表的引入

这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到了A。

具体我们画一张图

这里的B  C就像两个人分别在两个不同的地方,但是都要去A这个地方,保存了A的地址,那么就可以用地图去导航,但是因为两个人所在的地方不一样,所以到A的距离肯定也会不一样,也就是A的偏移量肯定会不一样(这样说会比较好理解一点)。

总结

很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有 菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度上就有问题并且菱形继承虚继承也带来了性能上的损耗(因为多开了地址来存放偏移量)。

到此这篇关于C++中的继承之菱形继承的文章就介绍到这了,更多相关C++继承之菱形继承内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一文读懂C++中的继承之菱形继承(案例分析)

本文链接: https://lsjlt.com/news/122736.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文读懂C++中的继承之菱形继承(案例分析)
    目录前言一、什么是多继承?1.单继承2.多继承二、菱形继承1.虚基类的引入2.虚基表的引入总结前言 我们上一篇说了世间万物都有一个继承体制,或多或少子类继承了父类的某些特征,但大多都...
    99+
    2024-04-02
  • C++数据结构继承的概念与菱形继承及虚拟继承和组合分析
    这篇“C++数据结构继承的概念与菱形继承及虚拟继承和组合分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++数据结构继承...
    99+
    2023-06-29
  • C++中的继承问题(继承基本概念、菱形虚拟继承的对象模型)
    目录一、继承的概念与定义格式概念及定义格式二、赋值兼容规则三、继承中的作用域四、子类的默认成员函数构造函数拷贝构造函数赋值运算符重载析构函数构造和析构函数调用顺序五、继承与友元、静态...
    99+
    2023-02-05
    C++的继承 继承基本概念 菱形虚拟继承
  • C++中菱形继承的解释与处理详解
    封装,继承,多态。这是C++语言的三大特性,而每次在谈到继承时我们不可避免的要谈到一个很重要的问题——菱形继承。 派生类继承父类,同时也会继承父类中的所有成员...
    99+
    2024-04-02
  • c++中继承关系的示例分析
    这篇文章给大家分享的是有关c++中继承关系的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 什么是继承继承概念继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序...
    99+
    2023-06-20
  • C++继承方式的示例分析
    这篇文章给大家介绍C++继承方式的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++支持多种程序设计风格,其中就包括对面向对象设计的支持。我们今天在这里将会为大家详细介绍一下各种C++继承方式的具体应用方法,...
    99+
    2023-06-17
  • javascript中继承的示例分析
    这篇文章主要介绍javascript中继承的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!javascript 中的继承实例详解阅读目录原型链继承借用构造函数组合继承寄生组合...
    99+
    2024-04-02
  • CSS中继承的示例分析
    小编给大家分享一下CSS中继承的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、说明解释   -  ...
    99+
    2024-04-02
  • js中继承的示例分析
    这篇文章给大家分享的是有关js中继承的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。继承的简介继承”是JavaScript面向对象设计的重要一环,愿你认真读完本文,吃透继...
    99+
    2024-04-02
  • 一文搞懂C++中继承的概念与使用
    目录前言继承概念及定义继承概念继承定义继承方式父类和子类对象赋值转换继承中的作用域派生类的默认成员函数派生类的友元与静态成员继承关系单继承多继承菱形继承前言 我们都知道面向对象语言的...
    99+
    2024-04-02
  • 详解C++中菱形继承的原理与解决方法
    目录菱形继承形成原因应对方案虚继承 vitrual解决二义性变量内存布局–虚基表感悟菱形继承形成原因 多继承,呈菱形状 菱形继承代码: class A { publi...
    99+
    2023-02-01
    C++菱形继承原理 C++菱形继承解决方法 C++菱形继承
  • Angular.JS中Scope继承的示例分析
    这篇文章主要介绍Angular.JS中Scope继承的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!基本原理在JavaScript中,每创建一个构造函数(constructo...
    99+
    2024-04-02
  • php中有限继承的示例分析
    这篇“php中有限继承的示例分析”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“php中有限继承的示例分析”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章有所收获,下面让我们一起...
    99+
    2023-06-06
  • javascript中实现继承的示例分析
    小编给大家分享一下javascript中实现继承的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!类式继承//声明父类//声明父类function SuperClass() { &nbs...
    99+
    2023-06-27
  • 一文带你掌握C++中的继承
    目录一、继承的概念及定义1.1继承的概念1.2继承的定义1.2.1继承的格式 1.2.2继承基类成员访问方式的变化1.2.3总结:二、基类和派生类对象赋值转换三、继承中的作...
    99+
    2023-05-19
    C++ 继承详解 C++ 继承
  • C++11继承的构造函数举例分析
    本篇内容主要讲解“C++11继承的构造函数举例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++11继承的构造函数举例分析”吧!假设我们有下面的CRect类:由于今天的内容是讲构造函数的,...
    99+
    2023-06-19
  • ES6 javascript中Class类继承的示例分析
    小编给大家分享一下ES6 javascript中Class类继承的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:1. 基本用法Class 之间可以通过extends关键字...
    99+
    2024-04-02
  • css中属性值继承的示例分析
    这篇文章主要介绍了css中属性值继承的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。继承:html元素可以从父元素那里继承一部分cs...
    99+
    2024-04-02
  • CSS中级联和继承的示例分析
    这篇文章主要为大家展示了“CSS中级联和继承的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CSS中级联和继承的示例分析”这篇文章吧。   1.在HT...
    99+
    2024-04-02
  • PHP中类继承关系的示例分析
    这篇文章将为大家详细讲解有关PHP中类继承关系的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在PHP中,我时常会写一个类,类写了一个共用方法,然后让子类去继承就...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作