目录
1.继承的概念
继承的出现就是为了解决重复类的问题。
如最常见的游戏开发中,我们编写了许多类,其中不少类都有共同点,共同的特性以及共同的实现这些特性的函数,如果将来这些代码需要迭代,那所有跟这些特性相关的代码都要去修改,岂不复杂死?
所以C++推出了继承这一概念,只需要声明一个基类(父类),基类通常定义为一个描述某个对象的类,如动物,人等,派生类通过继承父类,来扩展自己的一些特性,如,老师这个职业,老师这个职业肯定是人来当的,那么它就具有人的特性,如:年龄,身高,性别等特性,我们通过继承人这个父类,来实列我们的子类,这样就可以省去构造人这一特性的步骤。
同时人这个类也可以派生出,司机,打工人,干饭人,开挖掘机的等很多派生类。
如动物这个基类,它具有:睡觉,运动,吃饭等特性,那么我们可以通过派生动物这个基类,派生出老虎,狮子,大象,当然有食肉动物与食草动物,同时每个动物爱吃的东西都不同,通常情况下父类里爱好这些通常是虚函数,由我们重载实现每个动物的个性。
2.继承的三种方式
2.1 public:公有继承方式
2.1.1 可以访问父类的公有成员和保护成员
2.1.2 不能访问父类私有成员
2.1.3 可以使用父类的公有成员函数和保护成员函数去访问私有成员
2.2 protected:保护继承方式
2.2.1 父类的公有成员和保护成员的权限统一改为保护成员,私有成员不受影响,也就是说当通过派生类访问父类成员时,统一以保护成员权限
2.2.2 同时依然不能直接访问私有成员变量,但依然可以使用父类的公有成员函数和保护成员函数去访问私有成员
2.3 private
2.3.1 父类的公有成员和保护成员权限改为派生类的私有成员权限,也就是说,只能在派生类内部访问父类的成员,类外部无法直接访问
2.3.2 同时依然不能直接访问私有成员变量,但依然可以使用父类的公有成员函数和保护成员函数去访问私有成员但只能在类的内部
3.示列代码
#include <iostream>
//人的基类
class people_base{
public:
//父类的构造函数
people_base(){
Age = 0;
height = 0f;
weight = 0;
}
//父类的虚构函数
~people_base(){}
//修改属性的方法
void modify(int _par_age,float _par_height,int _par_weight){
Age = _par_age;
height = _par_height;
weight = _par_weight;
}
//父类的特性
int Age; //年龄
float height; //身高
int weight; //体重
};
//这里定义一个老师的职业,继承人这个基类,以公共的方式继承
class teacher public:people_base{
public:
//派生类的构造
teacher(){}
//派生类的析构
~teacher(){}
//设置老师科门
void set_course(std::string& course_name){
course = course_name;
}
std::string course; //这个老师是教哪个科门的
};
int main(){
//声明老师的派生类
teacher _var_math_teacher;
//设置老师的年龄以及身高体重,这里是调用父类的方法
//设置老师的年龄是34,身高1.75,体重180斤
_var_math_teacher.modify(34,1.75f,180);
//设置这个老师的教的是数学
_var_math_teacher.set_course("数学");
//打印出这个老师的资料
std::cout << "年龄:" << _var_math_teacher.Age << endl;
std::cout << "身高:" << _var_math_teacher.height<< endl;
std::cout << "体重:" << _var_math_teacher.weight<< endl;
std::cout << "教书:" << _var_math_teacher.course<< endl;
}
打印输出:
年龄:34
身高:1.75
体重:180
教书:数学
4.继承的构造与析构调用顺序
4.1 构造调用顺序
父类构造函数->子类构造函数
优先调用父类的构造函数,在调用子类的构造函数
4.2 析构调用顺序
子类析构函数->父类析构函数
优先调用子类析构函数,在调用父类析构函数