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++中的类继承之单继承&多继承&菱形继承的更多相关文章

  1. day35-2 类的三大特性---多态,以及菱形继承问题

    目录 菱形继承问题 经典类 新式类 菱形继承 大招 多态与多态性 多态 多态性 多态在Python中的体现 鸭子类型(重要) 结论 菱形继承问题 经典类 没有继承object类的就是经典类,只有Pyt ...

  2. Learn day7 继承(单、多、菱形)\多态\魔术方法\装饰器\异常

    1.继承 1.1 单继承# ### 继承 """ (1) 单继承 (2) 多继承 至少2个类,子类和父类 一个类继承另外一个类,当前类是子类 (衍生类) 被继承的这个类是 ...

  3. C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.

    C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形 ...

  4. C++反汇编第四讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.

    目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { ...

  5. C++反汇编-菱形继承

    学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记.马上就要出差了,回来后接着写吧. 一.概述 菱形继承是最复杂的对象结构,菱形结构会将单一继承与多重继承进行组合. ...

  6. C++中的类继承(4)继承种类之单继承&多继承&菱形继承

    单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可 ...

  7. C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)

    今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C ...

  8. Lua面向对象----类、继承、多继承、单例的实现

    (本文转载)学习之用,侵权立删! 原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...

  9. java类为什么是单继承。类的继承,实现接口。

    java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ Sy ...

随机推荐

  1. System.err.println()

    err是运行期异常和错误反馈的输出流的方向 System.err.println只能在屏幕上实现打印,即使你重定向了也一样 用err打印出的 字符串,再eclipse的console会显示成红色 标准 ...

  2. HDUOJ--4565 So Easy!

    So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. leetcode16 3-Sum

    题目链接 给定数组a[](长度不小于3)和一个数字target,要求从a中选取3个数字,让它们的和尽量接近target. 解法:首先对数组a进行排序,其次枚举最外面两层指针,对于第三个指针肯定是从右往 ...

  4. 为同一部电脑设置2个IP地址

    为同一部电脑设置2个IP地址 在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\NetTrans下 点击0000.0001,000 ...

  5. ant批量运行Jmeter脚本遇到 Content is not allowed in prolog.问题及解决方案

    在执行 最后生成报告的 task 时,一直报下面这个错: TransformerException,  Content is not allowed in prolog. 解决方法:需要修改jmete ...

  6. 最简单的回射客户/服务器程序、time_wait 状态

    下面通过最简单的客户端/服务器程序的实例来学习socket API. echoser.c 程序的功能是从客户端读取字符然后直接回射回去.  C++ Code  1 2 3 4 5 6 7 8 9 10 ...

  7. HDU 5092 DP

    DP水题 求从上到下走完,使所取得权值最小,并输出路径,若有多个满足,则输出靠右的 #include "stdio.h" #include "string.h" ...

  8. 中国计算机学会CCF推荐国际学术期刊会议(最新版)

    中国计算机学会推荐国际学术期刊会议 2014年12月,中国计算机学会(CCF)启动新一轮<)计算机体系结构/高性能计算/存储系统: )计算机网络:)网络与信息安全:)软件工程/系统软件/程序设计 ...

  9. java从Object类型转换成double类型

    java从Object类型转换为double类型: Map<String,Object> map = new HashMap<String,Object>(); map.put ...

  10. 【Android】8.4 让主题自适应不同的Android版本

    分类:C#.Android.VS2015: 创建日期:2016-02-17 一.简介 默认情况下,高版本提供的主题不能在低版本的Android系统上运行.但是,通过自定义主题,可以让你的系统自适应各自 ...