C++总复习--5--C++程序设计--继承与多态
C++总复习--5--C++程序设计--继承与多态
1.继承思想
2.虚函数,多态的思维
3.纯虚函数和抽象类
4.虚继承
C++ 三大特征:封装 继承 多态
继承:继承的本质:代码复用
1.继承和派生的关系
父类派生出子类 , 子类继承父类
2. 派生类继承了基类什么东西
- 普通的成员变量
- 普通的成员方法
- 静态的成员变量
- 静态的成员方法
除了构造和析构函数以外的所有成员
3.派生类的内存布局
基类的布局优先于派生类
4.派生类的构造函数析构顺序
Derive
(1)开辟内存
(2)调用构造函数
先是 基类的构造函数
然后 派生类的构造函数
先构造的后析构
5.继承方式
访问限定符:
Public: 任意
Protected:本类和子类
Private: 本类
继承方式:
Public
Protected
Private
基类中不同访问协定符下的成员,以不同的继承方式继承后,在派生类中的访问协定
public protected private
public public protected 不可访问
protected protected protected 不可访问
private private private 不可访问
6.类和类的关系
组合 a part of has_a
class 桌腿
Class 桌子
{
Private:
桌腿
}
继承 a kind of is_a
鸟 燕子
代理 限制底层接口
问:private继承是一个has_a还是一个is_a
答:has_a
7.同名函数的关系
(1)重载 overload 又名 重定义
静多态
(2)隐藏 overhide
(3)覆盖 override 又名 重写
动多态
问:重定义和重写的关系
答:先说重载是静多态,在编译时确定函数的调用
覆盖是动多态,在运行时确定函数的调用,动多态就是虚函数的处理,
在编译阶段,针对虚函数做一个备份,在.rodata(只读数据段)里面生成一个虚函数表存放虚函数的入口地址,数据段加载到内存中,在内存中拿到虚函数的入口地址,针对地址确定函数调用,来实现动多态。
多态:默认动多态,用虚函数做支持 关键词 : virtual
1.虚函数的处理机制
- 编译阶段
对象和虚函数表
对象里有虚函数指针vfptr,为实现对象和虚函数表的共享关系
2.vfptr和vftable
动多态的调用如下图:
3.虚表的合并和覆盖
继承机制
虚函数
基类中同名同参的函数是虚函数
那么派生类中同名同参的函数也是一个虚函数
派生类中继承的虚函数调用如下图所示:
4.多态
本质:接口复用
统一接口 不同形态
1.静多态 编译阶段确定函数的调用
函数重载 模板
2.动多态 运行阶段确定函数的调用
3.宏多态 预编译阶段确定函数的调用
5.虚函数机制
- 虚函数的处理流程
- vftable和处理流程
- 那些虚函数能成为虚函数
- 能取地址
- 依赖对象
(1)普通的类成员方法
(2)析构函数
4.虚析构
基类指针 指向派生类对象
解决办法:基类的析构函数设为虚析构
析构函数满足同名覆盖的关系
虽然析构函数不同名
vftable
5.过程
基类的虚表调用情况:
虚函数自己生成的未替换的表:
合并表之后:
派生类表中的继承合并后的内存布局
6.多态的发生时机
1.指针调用函数
2.对象完整
7.虚函数表的写入时机
构造函数的第一行代码执行之前
8.纯虚函数
1.保留接口
2.不能实现该接口
抽象类:比如:平面图形的面积
不能实例化对象
只能做指针或者引用来使用
派生类继承抽象类后,一定要实现该类
9.多重继承
一个派生类是由多个基类继承过来的
菱形继承
10.虚继承
vbtable 和 vbptr
11.内存布局***
- 非虚基类的布局优先于虚基类
- 虚基类的处理和继承顺序有序有关
- 虚基类指针合并