继承/派生
引入
职务:皇帝 职务:太子 太子->皇帝 即:太子继承皇帝或皇帝派生太子
概念
子类继承父类,父类派生子类
优点
子类拥有父类的所有的成员变量与成员函数
提高程序的编写效率,降低代码的耦合度(即代码关联性降低)
注意事项
要有继承关系
如:
狗:姓名,性别,年龄,吃喝,玩
猫:姓名,性别,年龄,吃喝,玩
人:姓名,性别,年龄,吃喝,玩
注意:此时三者毫无继承关系,虽然有相同的属性也不能产线继承关系
多个类抽取共同点形成的类可以与多个类产生继承关系
如:
动物:姓名,性别,年龄,吃喝,玩
则此时动物类与狗,猫,人这三类产生继承关系
即:
狗继承与动物
猫继承与动物
人继承与动物
不能继承的东西
父类的构造函数不能被继承
父类的析构函数不能被继承
父类的拷贝构造不能被继承
重载的=运算符不能被继承
友元
继承但无法直接使用
父类的私有成员变量
语法
class 子类名:继承方式1 父类名1,继承方式2 父类名2,继承方式3 父类名3,...
{
}
继承方式
public:父类成员修饰符是什么,子类继承后保持不变
protected:父类成员的修饰符为public的在子类继承后变成protected修饰,其余不变
private:父类的成员在子类中全部变为private的
建议:
public
练习:小明开了一个宠物医院,可以给猫,狗,鱼看病
父类:动物类
属性:姓名,性别,年龄,吃,喝,玩
子类:人类
属性:继承父类属性
父类:医院
属性:治病
子类:宠物医院
特殊属性:宠物治病
子类:人民医院
特殊属性:给人治病
子类:猫类
属性:继承父类属性
子类:狗类
属性:继承父类属性
子类:鱼类
属性:继承父类属性
构造与析构的顺序(继承关系中)
基础情况如下顺序:
1>父类构造函数
2>子类构造函数
3>子类析构函数
4>父类析构函数
父类中含有其他类成员时如下顺序:
先父类静态成员构造
再子类静态成员构造
(如果静态成员有多个则按照书写顺序执行)
1>先父类成员构造
如果成员中有多个对象,按照书写顺序构造
2>再父类构造
3>再子类成员构造
4>再子类构造
5>子类析构
6>子类成员析构
如果成员中有多个对象,按照书写的逆反顺序析构
7>父类析构
8>父类成员析构
(如果有多个静态成员则按照书写的逆反顺序进行析构)
先子类静态成员析构
再父类静态成员析构
口诀:
先父静,再子静,父非静,父构造,子非静,子构造,析构反向进行.
子类调用父类及其成员的构造函数
子类调用父类
1>定义位置
子类构造函数初始化列表中
2>语法:
父类名(实参列表)
3>注意;
顺序无所谓
子类调用自己成员
1>定义位置
子类构造函数初始化列表中
2>语法:
子类成员对象名(实参列表)
3>注意:
无顺序
继承练习:
子父成员重名
成员变量名重名区分
语法:
子类 子类对象.成员变量
父类 子类对象.父类名::成员变量
成员函数名重名区分
语法:
子类 子类对象.成员函数
父类 子类对象.父类名::成员函数
多继承(了解)
class 子类名:继承方式1 父类名1,继承方式2 父类名,...
可能会造成子父成员重名以及构造和析构顺序混乱问题
#include <iostream>
using namespace std;
class A{};
class B{};
class C:public A,public B{};
int main()
{
return 0;
}
菱形继承(了解)
引入:
动物类
驴类 马类
骡子类
概述:
动物类派生了驴类和马类,而骡子累继承了驴类和马类,此时就是菱形继承
此时D类中有两份来自动物类提供的成员变量与成员函数
解决这个问题,需要使用虚继承
虚继承(解决菱形继承)
关键字:
virtual
虚继承语法:
class 子类:virtual 继承方式1 父类名;virtual 继承方式2 父类名,...
{
}
虚继承原理:
虚继承会生成虚基指针与虚基表
通过虚基指针查询虚基表中的内容,指定其位置,多个虚基指针会指向同一片内存,从而解决菱形继承导致的子类拥有多分成员变量的问题.