简介

本课程将带领大家体会C++面向对象三大特性中的继承特性,讲述了基类、派生类的概念,公有继承、保护继承和私有继承、多重继承及多继承,虚析构函数及虚继承的作用,理解课程内容对于面向对象的学习将大有裨益,所有知识均通过编码实践的方式讲解到操作层面,力求即学即会。

第2章 为什么继承

2-1 为什么继承(05:29)

基类和派生类(子类)的关系:公有继承、保护继承、私有继承。分清多重继承和多继承
父类对应基类,子类对应派生类 不可以混用
class 工人类:public 人类 //工人类继承人类的格式,public为继承方式

第3章 继承方式

3-1 [C++]公有继承(06:32)

3-3 [C++]保护继承私有继承…(04:17)

保护继承过来的成员都是在保护里面,私有继承过来的都在私有里面,共有继承还是在原来的里面。
外部(即main函数)初始化对象后,不能访问对象中的保护和私有成员。
私有成员不能被继承。
B类从A类派生,那么B类中含有A类的所有数据成员。私有成员是隐藏的,不能访问,但继承过来了。

第4章 继承中的特殊关系

4-1 [C++]隐藏(06:44)

1
2
3
4
5
#include<> 用<>包含的文件,系统会到程序相应的默认库中去寻找
#include"" 用""包含的文件,系统会到本程序的目录下去寻找
子类继承父类的函数和子类的函数同名,那么父类的函数会被隐藏,实例化子类的对象能访问到子类的这个函数,却不能访问到父类的这个同名函数,要访问父类的同名函数,要用 .子类对象.父类类名::同名函数 的方式访问到父类的同名函数, :: 可以理解为<br>
** 下的 成员。从而区分来准确找到所要访问的成员。对于数据成员的隐藏也是如此。<br>
一般不做数据成员的隐藏,而是采用有区别的命名方式区分父类和子类不同的数据成员。

父子关系,成员同名,隐藏。

4-4 [C++]isA(07:24)

isA概念:

(1)当一个子类的对象去初始化或者对一个父类的对象赋值时,本质上就是把子类从父类所继承下的数据成员赋值给父类的原有的数据成员,此时子类对象的其他数据成员就会丢失

(2)若是父类的一个对象指针指向一个子类的对象,则访问,也只能访问到从父类继承下来的数据成员。(本质上都是在访问自己数据成员所在的内存空间,人为概念上区分了,但是硬件本质上操作的还是同一块内存区域),子类独有的数据成员及成员函数是无法被访问的。

4-5 [C++]isa(编码一)(10:49)

test(person p):调用时会产生一个临时对象,并会执行析构函数
test(person *p):不会产生临时的对象
test(person &p):不会产生临时的对象
所以采用指针和引用的执行速度更快

第5章 多继承与多重继承

5-1 [C++]多继承和多重继承(…(02:57)

多继承: 一个子类同时有两个父类,两个父类关系是平行的。
多重继承,继承的层数。是多层的。
多继承区别于多重继承,多继承是一个子类有多个父类,而多重继承是一个父类和子类连续继承的关系,形成链条式的关系。

5-2 [C++]多重继承代码演示…(05:32)

在最底层的类,要实例化对象,就必须执行继承量当中的每一个类

在销毁的时候,逆序执行
无论继承有多少级,只要保持间接或者直接的关系,子类都可与自己的直接父类,或者是间接父类,称之为is a 的关系,并且能够通过父类的指针对直接子类或者是间接子类的对象进行操作。

5-5 巩固练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

/**
* 定义工人类: Worker
* 数据成员: m_strName
* 成员函数: work()
*/
class Worker
{
public:
Worker(string name)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};

/**
* 定义儿童类: Children
* 数据成员: m_iAge
* 成员函数: play()
*/
class Children
{
public:
Children(int age)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};

/**
* 定义童工类: ChildLabourer
* 公有继承工人类和儿童类
*/
class ChildLabourer : public Worker, public Children
{
public:
ChildLabourer(string name, int age):Worker(name), Children(age)
{
cout << "ChildLabourer" << endl;
}

~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};

int main(void)
{
// 使用new关键字创建童工类对象
ChildLabourer *childLabourer = new ChildLabourer("hejian", 23);
// 通过童工对象调用父类的work()和play()方法
childLabourer->work();
childLabourer->play();
// 释放
delete childLabourer;
childLabourer = NULL;

return 0;
}

第6章 虚继承

6-1 [C++]虚继承(理论)…(03:51)

D中继承了两份A,这种冗余数据,我们没有办法来承担他的系统开销
避免重复继承数据,用virtual进行虚继承(菱形继承关系)

菱形继承
多继承和多重继承会出现问题呢?
如图,假设类a是父类,b类和c类都继承了a类,而d类又继承了b和c,那么由于d类进行了两次多重继承a类,就会出现两份相同的a的数据成员或成员函数,就会出现代码冗余。

如何避免该情况的发生,就可以使用虚继承virtual

6-2 [C++]虚继承(编码一)…(08:02)

初始化列表很好用。

6-4 巩固练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

/**
* 定义人类: Person
*/
class Person
{
public:
Person()
{
cout << "Person" << endl;
}
~Person()
{
cout << "~Person" << endl;
}
void eat()
{
cout << "eat" << endl;
}

};

/**
* 定义工人类: Worker
* 虚继承人类
*/
class Worker : virtual public Person
{
public:
Worker(string name)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};

/**
* 定义儿童类:Children
* 虚继承人类
*/
class Children : virtual public Person
{
public:
Children(int age)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};

/**
* 定义童工类:ChildLabourer
* 公有继承工人类和儿童类
*/
class ChildLabourer:public Worker, public Children
{
public:
ChildLabourer(string name, int age):Worker(name), Children(age)
{
cout << "ChildLabourer" << endl;
}

~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};

int main(void)
{
// 用new关键字实例化童工类对象
ChildLabourer *p = new ChildLabourer("hejian", 23);
// 调用童工类对象各方法。
p->eat();
p->work();
p->play();
delete p;
p = NULL;

return 0;
}