C++继承和派生

C++继承和派生

图:古老的地球

Guderian出品

本文整理自《北京大学公开课:C++面向对象程序设计》

基本概念

  • 继承派生实际上是一回事:在定义一个新的类B时,如果该类与某个已有的类A相似(指的是B拥有A的全部特点),那么可以把A作为一个基类,而把B作为基类的一个派生类(也称子类),这使得创建和维护一个程序更加容易
  • 派生类拥有基类的全部特点,派生类还可以对基类进行修改和扩充。在派生类中,可以扩充新的成员变量和成员函数
  • 派生类一经定义,可以独立使用,定义对象时不依赖于基类
  • 派生类拥有基类的全部成员函数和成员变量。不论是privateprotectedpublic
  • 派生类的各个成员函数中,不能访问基类private成员

简单理解成员修饰符protectedprivate的区别:protected成员在派生类中可以被访问,而private不能

  • 对象不同类型对应的访问权限:
类型 public protected private
本类
派生类 ×
其他类 × ×

派生类的写法

1
2
3
4
5
class 派生类名: 访问修饰符 基类名	//Zh
class derived-class: access-specifier base-class //En
{
//...
};

访问修饰符可以是privateprotectedpublic中的一个。如果未使用访问修饰符,则默认为private。该访问修饰符规定了继承类型

继承类型

  • 公有继承(public):继承publicprotected且类型不变,不继承private
  • 保护继承(protected):继承publicprotected且类型都为protected,不继承private
  • 私有继承(private):继承publicprotected且类型都变为private,不继承private

一般使用公有继承。

写法示例:学生管理系统

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
class CStudent
{
private:
string sName;
int nAge;
public:
bool IsThreeGood() {};
void SetName(const string & name) { sName = name; }
//...
};
class CUndergraduteStudent: public CStudent
//本科生
{
private:
int nDepartment;
public:
bool IsThreeGood() {/*...*/}; //覆盖(不是重载!覆盖的参数表不变,重载的参数表改变!)
//名字与基类一样,但行为不一样
bool CanBaoYan() {/*...*/};
};
class CGraduatedStudent: public CStudent
//研究生
{
private:
int nDepartment;
char szMentorName[20];
public:
int CountSalary() {/*...*/};
};

派生类对象的内存空间

派生类对象的体积 = 基类对象的体积 + 派生类对象自己的成员变量的体积。

在派生类对象中,包含基类对象,而且基类对象的存储位置位于派生类对象新增的成员变量之前

学籍管理程序实现

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
#include <iostream>
#include <string>

using namespace std;

class CStudent
{
private:
string name;
string id;
char gender;
int age;
public:
void PrintInfo();
void SetInfo(const string & name_, const string % id_, int age_, char gender_);
string GetName() { return name; }
};

class CUndergraduteStudent: public CStudent
{//本科生类,继承了CStudent类
private:
string department; //学生所属的系的名称
public:
void QualifiedForBaoyan() //给予保研资格
{
cout << "qualified for baoyan" << endl;
}
void PrintInfo()
{
CStudent::PrintInfo(); //调用基类的PrintInfo
cout << "Department" << department << endl;
}
void SetInfo(const string & name_, const string % id_, int age_, char gender_)
{
CStudent::SetInfo(name_, id_, age_, gender_); //调用基类的SetInfo
department = department_;
}
};

int main()
{
CUndergraduteStudent s2;

s2.SetInfo("Guderian", "999999999", 21, "M", "Combat Command");
//古德里安,999999999,,2岁,男性,战役指挥学
s2.QualifiedForBaoyan();
//获得保研资格
s2.PrintInfo();
//打印信息

return 0;
}

//输出:
Guderian qualified for baoyan
Name: Guderian
ID: 999999999
Age: 21
Gender: M
Department: Combat Command

派生类的使用方法

  • 在派生类中,调用基类的成员函数,设置了从基类继承的信息之后,之后再设置自己独有的信息。这一方法在C++面向对象编程中是很常用的。
  • 多继承:一个子类可以有多个父亲,继承多个父亲的特性

参考并整理自《C++面向对象设计》郭炜,北京大学,感谢原作者!编辑时有删改

本文标题:C++继承和派生

文章作者:G-SS-Hacker

发布时间:2019年12月06日 - 21:51:21

最后更新:2020年01月30日 - 10:36:48

原始链接:https://G-SS-Hacker.github.io/C-继承和派生/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。