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环境下用的是偏移量,而不是图中的直接指针指向这里只是为了更直观的展示。

时间: 2024-02-24 10:36:28

C++中的类继承之单继承&多继承&菱形继承的相关文章

es6中class类的全方面理解(二)------继承

继承是面向对象中一个比较核心的概念.ES6 class的继承与java的继承大同小异,如果学过java的小伙伴应该很容易理解,都是通过extends关键字继承.相较于ES5当中通过原型链继承要清晰和方便许多.先上代码: class Cucurbit{ constructor(name,color){ console.log("farther") this.name=name; this.color=color; } say(){ console.log("我的名字叫"

面向对象概论之继承简述,组合简述,菱形继承简述

一.继承 1.简述: 用来表述的是类与类之间的关系,比如A继承了B,那么A会有B已有的方法和属性. 那么A称为子类,B为父类.(父类又叫:基类) 使用继承可以不再用重复写代码的情况下,从而重复使用代码. 提高了编程效率. 2.正确使用继承思想:       1.先抽象然后再继承       2.继承已经存在的类,可拓展或是修改原始功能 3.在继承里的属性查找顺序: 对象自己的----->所在的类中----->父类----->父类的父类------->Object 4.继承语法表达:

python 单继承、多继承、菱形继承

单继承与多继承 单继承:一个类只能继承一个父类的方式.多继承:一个类可以继承多个父类的方式. 单继承:(生物角度) 人类->哺乳类动物->动物->生物->有机物.... 多继承:(社会角度) 舞蹈老师(教舞蹈) 体育老师(运动) 爸爸(抽烟) 妈妈(打扫卫生) 我(舞蹈,运动,抽烟,打扫卫生) 单继承案例: 父类: pass 子类(父类): pass 多继承案例: 父类1: pass 父类2: pass 父类3: pass 子类(父类1,父类2,父类3): pass 多继承的问题所

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

目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { public: Father1(){}//空构造 virtual ~Father1(){} //空析构 virtual void Player(){} //玩耍的函数 int m_price;//金钱 }; class Father2 { public: Father2(){} virtual ~F

C++中对C的扩展学习新增内容———面向对象(继承)多继承和虚继承

多继承和虚继承 1.多继承的优缺点 (1) 多继承可以复用多个类的代码(函数,变量). (2) 多继承会带来二义性问题. // 1. 多继承优缺点 class Flyable { public: void fly() { cout << "飞翔..." << endl; } void sound() { cout << "嗖嗖..." << endl; } }; class Runnable { public: voi

C++之菱形继承

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

菱形继承的内部实现方式

问题: 由于将下图定义为多继承类型时,子类会发生二义性与数据冗余,而用菱形继承时会解决这些问题,菱形继承发生了些什么?又是怎么实现的? 本次试着说明菱形继承的机理(实现方法) 按照上图建立多继承,编写代码: class Base { public:  virtual void func1()  {   cout << "Base::func1()" << endl;  } protected:  int _a; }; class Base1: public Ba

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

java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ System.out.println("父类1"); } } class Fulei2{ public void show(){ System.out.println("父类2"); } } class Zilei extends fulei1,fulei2{ public

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

(本文转载)学习之用,侵权立删! 原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&utm_medium=referral lua面向对象实现: 一个类就像是一个创建对象的模具.有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例.lua则没有类的概念,每个对象只能自定义行为和形态.不过,要在lua中模拟类也并不困难. lua中,面向对象是用元表这个机制来实现.