【C++】虚拟菱形继承的解析

在继承中经常会遇到这种情况:有一个超类A,子类B1,B2继承了A,而类D又继承了父类B1,B2。在这种情况下如果按照我们以前的正常的菱形继承的话会有一个问题是子类C会继承两次超类A中的成员,当在C中想访问继承来自B1,B2中A的元素会出现两个问题:

问题一、数据的冗余

问题二、访问的二意性

出现了这种问题那么我们该如何解决呢?

C++中为了解决这个问题引入了虚拟菱形继承,那么虚拟菱形继承是怎么解决的呢?

首先给大家先画两个图比较下菱形继承和虚拟菱形继承在继承时在内存中的成员分布情况:

一、 菱形继承:

没有继承以前的超类A和父类B1,B2;

继承超类A以后的B1,B2;

子类D继承B1,B2以后的内存分布情况

通过图我们可以看出菱形继承存在很多的数据冗余,如超类A的成员ia,ca都有两份,访问时也会出先二义性的错误。

二、虚拟菱形继承

没有继承以前的超类A和父类B1,B2;

虚拟继承超类A以后的B1,B2;

虚拟继承B1,B2后的D;

看完分布图以后,我们代码在内存中的分布

				
时间: 2024-11-05 23:29:08

【C++】虚拟菱形继承的解析的相关文章

C++中的类继承之单继承&多继承&菱形继承

 C++中的类继承之单继承&多继承&菱形继承 单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可以继承多个父类的特性.多继承可以看作是单继承的扩展.派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承.多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用.同时,派生类的参数个数必须包

菱形继承

学习了C++的继承,觉得菱形继承是比较难懂的一部分,通过了解菱形继承,我们可以了解编译器是如何工作的,下面介绍一下菱形继承在内存中的实现方式. 首先简单了解一下虚继承,下面父类和子类的大小分别是多少? class Base { public:              virtual void fun1()             {                         cout << "Base::fun1()" << endl;         

C++继承详解之三——菱形继承+虚继承内存对象模型详解vbptr(1)

在我个人学习继承的过程中,在网上查阅了许多资料,这些资料中有关菱形继承的知识都是加了虚函数的,也就是涉及了多态的问题,而我在那个时候并没有学习到多态这一块,所以看很多资料都是云里雾里的,那么这篇文章我想以我自己学习过程中的经验,由简到较难的先分析以下菱形继承,让初学者先对这个问题有一点概念,在后面会由浅入深的继续剖析. 本篇文章不会涉及到多态也就是虚函数的菱形继承,在后面的文章更新中,我会慢慢把这些内容都加进去. 菱形继承(也叫钻石继承)是下面的这种情况: 对应代码如下: #include <i

C++之菱形继承

当我们谈C++时,我们谈些什么? 封装,继承,多态.这是C++语言的三大特性,而每次在谈到继承时我们不可避免的要谈到一个很重要的问题--菱形继承. a.菱形继承是什么 如上图,菱形继承即多个类继承了同一个公共基类,而这些派生类又同时被一个类继承.这么做会引发什么问题呢,让我们来看一段代码吧! #include<iostream> using namespace std; class Base { protected: int _base; public: void fun() { cout &

C++对象内存分布(2) - 菱形继承(non virtual)

1.前言 本篇文章的所有代码例子,如果是windows上编译运行,则使用的是visual studio 2013.如果是RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686)上编译运行,则其gcc版本为4.4.7,如下所示: [[email protected] ~]# gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4) 2.菱形继承类的内存分布 2.1.类的结构 菱形继承 - 重复继承 2.2.实现

处理菱形继承问题&&实现一个虚函数的覆盖及调用&&实现以下几个类的成员函数

#include <iostream> #include <string> using namespace std; 1.实现以下几个类的成员函数 2.实现一个虚函数的覆盖及调用 3.处理菱形继承问题. 植物 class Botany { public: //(const string& name) // const char* name Botany(const char* name = "") :_name(name) //构造函数 { //cout

菱形继承问题(钻石问题)

在学习C++的时候,菱形继承问题绝对是一个不可避免的重点问题,那么什么是菱形继承问题呢?下图就是,长得像不像钻石?我画图确实很难看 因为C++允许多继承,当继承关系像上图这样子的时候,就会出现这样子的情况 A类是基类,B里面有个A我表示为B(A),C里面有个A我表示为C(A) 那么D里面有B和C我表示为D(B(A)C(A)) 当我们想去使用D里面的A的时候,或者说访问A的部分值,在说白了究竟哪个A才是属于D的,D中的A究竟是B的A还是C的A? 1 class A 2 {}; 3 class B

c++ 植物类 继承多态 菱形继承

#pragma once//头文件 #include <iostream> #include<string> using namespace std; // // 1.实现以下几个类的成员函数 // 2.实现一个虚函数的覆盖及调用 // 3.处理菱形继承问题. // // 植物 class Botany { public: Botany(const string&  name); virtual ~Botany(); virtual void Display(); Bota

C++对象内存分布(3) - 菱形继承(virtual)

1.前言 本篇文章的所有代码例子,如果是windows上编译运行,则使用的是visual studio 2013.如果是RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686)上编译运行,则其gcc版本为4.4.7,如下所示: [[email protected] ~]# gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4) 2.菱形继承类的内存分布 本篇文章主要讨论的是虚继承(virtual)下的内存分