余睿的博客

浮生若梦,别多会少,不如莫遇

0%

c++继承及派生基本概念

基本概念

继承:在定义一个新的类B时,如果该类与某个已有的类A相似(B拥有A的全部特征),那么就可以把A作为一个基类,而把B作为基类的一个派生类(也成为子类)。

  • 派生类是通过对基类进行修改和扩充得到的。在派生类中,可以扩充新的成员变量或成员函数。
  • 派生类一旦定义后,可以独立使用,不依赖于基类。
  • 派生类拥有基类的全部成员函数和成员变量。不论是publicprotected还是private
  • 在派生类的各个成员函数中,不能访问基类的private成员

例子

假设我们需要编写一个学生类,我们可以先将其基本信息抽象出来组成一个基类。

所有学生都有的共同属性:

  • 姓名
  • 学号
  • 性别
  • 成绩

所有学生都共有的方法:

  • 是否留级
  • 是否奖励

而不同种类的学生,又有各自不同的种类和方法,例如:

研究生

  • 导师

大学生

中学生

  • 特长加分

此时我们可以将上面的学生类作为基类派生出研究生类、大学生类以及中学生类

样例

派生类基本写法格式

1
2
3
class 派生类名:public 基类名{

};

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student {
private:
int age;
public:
string name;
int ID;
bool isThreeGood() {}
void setName(string name) { this->name = name; }
};

class UndergraduateStudent :public Student {
private:
int department;
public:
bool isThreeGood() {}//覆盖基类
};

如上代码所示,UndergraduateStudent类从Student类派生得到,所以UndergraduateStudent拥有基类的全部属性。

需要注意的是,在UndergraduateStudent类中,我们再次定义了函数isThreeGood(),与基类中的相同,此时派生类中的该函数会对基类中的该函数进行覆盖。也就是说,当我们直接调用isThreeGood()时调用的是派生类中的该函数,如果需要调用基类的isThreeGood(),我们需要将其写成Student::isThreeGood()

派生类对象的内存空间

派生类对象的体积,等于基类对象的体积,再加上派生类对象自己的成员变量的体积。在派生类对象中,包含着基类对象,而且基类对象的存储位置于派生类对象新增的成员变量之前。

例如上面的学生类以及研究生类的存储关系可由下图表示:

派生类对象的内存空间

派生类样例

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
class Student {
private:
int age;
public:
string name;
int ID;
void setInfo(string name, int ID, int age) {
this->name = name;
this->ID = ID;
this->age = age;
}
void print() {
cout << "name:" << name << endl;
cout << "age:" << age << endl;
cout << "ID:" << ID << endl;
}
};

class UndergraduateStudent :public Student {
private:
int department;
public:
void setInfo(string name, int ID, int age, int department) {
Student::setInfo(name, ID, age);//调用基类构造函数初始化
this->department = department;
}
void print() {//覆盖基类print()
Student::print();//调用基类print()
cout << "department:" << department << endl;
}
};

int main() {
UndergraduateStudent stu;
stu.setInfo("jack", 1, 22, 5);
stu.print();//调用派生类print()
return 0;
}

还是上面的学生类以及研究生类,我们通过setInfo()函数设置学生信息,通过print()函数打印出学生的信息。

需要注意的是:

  • 当派生类中有成员函数或成员变量名与基类相同时,则基类的成员函数或变量将被覆盖。直接访问该成员函数或变量时访问的为派生类的成员函数或变量,需要访问基类的成员函数或变量时需要在成员函数或变量名前加上基类名::才能正常访问。
  • 在上面的样例中,基类以及派生类中均有setInfo()以及print()两种方法,直接访问时为派生类的方法,在派生类中通过Student::访问基类的方法。

运行上面的程序,得到如下结果:

1
2
3
4
name:jack
age:22
ID:1
department:5

欢迎关注我的其它发布渠道