定义:
子类(派生类)继承了父类(基类)的成员函数和成员变量(类层次的复用)
赋值
子类可以赋值给父类。父类不可以直接复制给子类
(不像不同内置类型的赋值要转化为临时变量)
不产生临时变量,直接切割子类的父类那一块,然后赋值给父类
class Person
{
protected:string _name; // 姓名string _sex;// 性别int _age; // 年龄
};class Student : public Person
{
protected:int _No; // 学号
};int main()
{Student st;Person pe = st;//子类截断赋值给父类return 0;
}
作用域(隐藏)
子类和父类虽然存在继承关系,但他们任然是两个不同的作用域,允许存在同名变量,函数。
子类会隐藏父类同名变量
成员函数名相同就构成隐藏
注意:实践当中尽量不要写同名变量,函数
子类的默认构造函数
不写:父类的那部分直接默认调用父类的构造函数,
父类的那部分就相当于自定义类型去调用自己的默认构造
写:子类的默认构造函数只可以初始化自己本身就有的,不能初始化继承的变量,继承的变量要由父类的默认构造函数自己来初始化
但是我们想要在实例化子类对象的时候,改变父类的成员变量的是该怎么办呢
——在子类的默认构造函数中调用父类的构造函数
且子类中的构造函数的构造顺序是,先父后子,因为父成员变量是继承下来的,声明顺序一定在前面
子类的拷贝构造
和切片联系
同样子类的拷贝构造不可以直接拷贝构造父类的那一部分,需要调用父类的拷贝构造,传参的时候直接把子类对象传过去,然后发生切片就行
赋值
赋值同样是先去调用父类的赋值(发生切片),在赋值子类本身的变量
析构函数
不同:析构函数会构成隐藏关系(因为析构函数会被特殊处理为同名函数)
所以在显示写子类函数的析构函数时,父类的析构函数是需要指定作用域的
但是有问题:因为子类的析构,是先子后父的
所以子类的析构中不用写父类的析构函数,如果写了就会先析构父类
所以不用写
继承与友元
父类的友元不是子类的友元
如果类也想使用这个友元函数的话,也需要在子类中声明这个友元
静态成员的继承——公有的
多继承
但是当菱形继承的时候就会出现二义性
解决办法,在会发生冗余的地方(腰部)继承的时候前面加 virtual
让二义级继承变量合成一个变量
class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person
{
protected:int _num; //学号
};
class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
int main()
{Assistant a;a._name = "peter";return 0;
}