C++中的类继承之单继承&多继承&菱形继承
C++中的类继承之单继承&多继承&菱形继承
单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承。这种关系比较简单是一对一的关系:
多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承。这种继承方式使一个子类可以继承多个父类的特性。多继承可以看作是单继承的扩展。派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。同时,派生类的参数个数必须包含完成所有基类初始化所需的参数个数。在子类的内存中它们是按照声明定义的顺序存放的,下面的截图将清晰看到。但是多继承存在一个问题,要想研究这个问题,我们先从单继承讲起。来看内存空间:
class Base
{
public:
Base() {
cout << "B()" << endl;
}
int b1;
};
class Derive : public Base
{
public:
Derive() {
cout << "D()" << endl;
}
int d1;
};
int main()
{
Test();
getchar();
return 0;
}
多继承的内存空间:
class Base
{
public:
Base() {
cout << "B()" << endl;
}
int b1;
};
class C
{
public:
C() {
cout << "C()" << endl;
}
int c;
};
class Derive : public Base, public C
{
public:
Derive() {
cout << "D()" << endl;
}
int d1;
};
菱形继承内存中数据分布:
class A
{
public:
A() {
cout << "A()" << endl;
}
int a;
};
class Base:public A
{
public:
Base() {
cout << "B()" << endl;
}
int b1;
};
class C: public A
{
public:
C() {
cout << "C()" << endl;
}
int c;
};
class Derive : public Base, public C
{
public:
Derive() {
cout << "D()" << endl;
}
int d1;
};在A类中初始化int a=4则可清楚的看到菱形继承中内存分布
所以子类Derive中有两份A类中的数据成员,这造成了访问二义性和数据冗余的问题
这就是我前面说的多继承存在的问题。可以这样访问
1 tmp.C::a=4;
2 tmp.Base::a=5;
什么是对象模型
有两个概念可以解释C++对象模型:
1、语言中直接支持面向对象程序设计的部分。
2、对于各种支持的底层实现机制。
还有另外一个方法解决这个问题,我们要用到一种新的继承方法:虚继承--解决菱形继承的二义性和数据冗余的问题。看下面这段代码:

1 class Base
2 {
3 public:
4 Base() {
5 cout << "B()" << endl;
6 }
7 int b1;
8 };
9 class Derive : virtual public Base
10 {
11 public:
12 Derive() {
13 cout << "D()" << endl;
14 }
15 int d1;
16 };
17 void Test()
18 {
19 Derive tmp;
20 tmp.d1 = 1;
21 tmp.b1 = 2;
23 }
24 int main()
25 {
26 Test();
27 getchar();
28 return 0;
29 }

虚拟继承的关键字---virtual

1 class A
2 {
3 public:
4 A() {
5 cout << "A()" << endl;
6 }
7 int a ;
8 };
9 class Base : virtual public A
10 {
11 public:
12 Base() {
13 cout << "B()" << endl;
14 }
15 int b1;
16 };
17 class C:virtual public A
18 {
19 public:
20 C() {
21 cout << "C()" << endl;
22 }
23 int c;
24 };
25 class Derive : virtual public Base, virtual public C
26 {
27 public:
28 Derive() {
29 cout << "D()" << endl;
30 }
31 int d1;
32 };
33 void Test()
34 {
35 Derive tmp;
36 tmp.d1 = 1;
37 tmp.b1 = 2;
38 tmp.c = 3;
39 tmp.a = 4;
40 }
41 int main()
42 {
43 Test();
44 getchar();
45 return 0;
46 }

菱形虚拟继承的对象模型解决二义性问题在vs环境下用的是偏移量,而不是图中的直接指针指向这里只是为了更直观的展示。
C++中的类继承之单继承&多继承&菱形继承的更多相关文章
- day35-2 类的三大特性---多态,以及菱形继承问题
目录 菱形继承问题 经典类 新式类 菱形继承 大招 多态与多态性 多态 多态性 多态在Python中的体现 鸭子类型(重要) 结论 菱形继承问题 经典类 没有继承object类的就是经典类,只有Pyt ...
- Learn day7 继承(单、多、菱形)\多态\魔术方法\装饰器\异常
1.继承 1.1 单继承# ### 继承 """ (1) 单继承 (2) 多继承 至少2个类,子类和父类 一个类继承另外一个类,当前类是子类 (衍生类) 被继承的这个类是 ...
- C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.
C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形 ...
- C++反汇编第四讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.
目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { ...
- C++反汇编-菱形继承
学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记.马上就要出差了,回来后接着写吧. 一.概述 菱形继承是最复杂的对象结构,菱形结构会将单一继承与多重继承进行组合. ...
- C++中的类继承(4)继承种类之单继承&多继承&菱形继承
单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可 ...
- C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化 译 译者前言 一个C ...
- Lua面向对象----类、继承、多继承、单例的实现
(本文转载)学习之用,侵权立删! 原文地址 http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...
- java类为什么是单继承。类的继承,实现接口。
java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ Sy ...
随机推荐
- CSS:关于CSS Hack
CSS Hack由于不同厂商的浏览器,如Internet Explorer,Safari,Mozilla Firefox,Chrome 等,或者是同一厂商的浏览器的不同版本,如IE6和IE7,对CSS ...
- 解决修改计算机名后tfs连接不上的错误
1,用vs 自带的工具命令 tf workspaces 查看集合 2,执行命令: >tf workspaces /collection:https://aaaa.visualstudio.com ...
- vim 折叠
zR 打开全部折叠 zr 打开当前折叠 zM 关闭全部折叠 zm 关闭当前折叠
- 后缀crt证书转换
转换地址:https://www.chinassl.net/ssltools/convert-ssl.html 转换成功后点下载即可
- 整理了一份招PHP高级工程师的面试题(转)
1. 基本知识点 HTTP协议中几个状态码的含义:1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 100 (继续) 请求者应当继续提出请求. 服务器返回此代码 ...
- 赶集mysql军规
总是在灾难发生后,才想起容灾的重要性.总是在吃过亏后,才记得曾经有人提醒过. 一,核心军规 不在数据库做计算,cpu计算务必移至业务层 控制单表数据量,单表记录控制在千万级 控制列数量,字段数控制在2 ...
- An example of using Pandas for regression
An example of using Pandas for regression 这个例子来自这本书 - "Python for Data Analysis", 这本书的作者 W ...
- Python文件遍历二种方法
分享下有关Python文件遍历的两种方法,使用的OS模块的os.walk和os.listdir实现. 关于Python的文件遍历,大概有两种方法,一种是较为便利的os.walk(),还有一种是利用os ...
- 记一次Animator状态快速切换问题的解决
事情是这样的,我尝试在一帧内多次切换一些状态(当前状态为Idle的情况下): public Animator animator; void OnEnable() { animator.CrossFad ...
- PCIE的DMA和PIO介绍
墨尘 百家号01-2422:14 在PCIE中有两种数据传输方式: DMA(Direct Memory Access),直接内存访问,在该模式下,数据传送不是由CPU负责处理,而是由一个特殊的处理器D ...