一、继承
1、本质:代码复用
class Student : public People
:继承列表
public 继承方式
2、派生类继承了基类的什么东西 //除了构造和析构以外的所有方法
(1)成员方法
(2)成员变量
(3)静态的成员变量
(4)静态的成员方法
(5)作用域
3、为什么构造和析构不能被继承
构造函数,析构函数与类名相同
4、派生类对象的内存布局
基类的布局优先于派生类
5、派生类的构造和析构方式
构造:
(1)开辟内存
(2)调用构造
销毁:
(1)调用析构
派生类的析构、基类的析构
(2)释放资源
6、继承的方式
(1)public:公有继承
(2)protected:保护继承
(3)private:私有继承
7、访问限定符
(1)public:任意访问
(2)protected:本类和子类
()private:本类
派生类\基类 | public | protected | private |
public | public | protected | 不可访问 |
protected | protected | protected | 不可访问 |
private | private | private | 不可访问 |
8、类和类的关系
(1)组合 a part of has_a
(2)继承 a kind of is_a
(3)代理 //限制了被代理类的接口的功能的字集 容器适配器
9、同名函数的关系 //基类和派生类成员方法的关系
(1)重载 overload 重定义
三要素:同名、不同参、同作用域
(2)隐藏 overhide //存在看不见,加作用域就可以看见了
隐藏了:派生类中同名的函数隐藏了基类中所有同名的函数
满足条件:
a)不同的作用域 //继承的条件下
b)同名
(3)覆盖 override(重写)
覆盖是在编译阶段发生的,核心是给多态支持的
基类中同名同参的函数是虚函数,派生类这个同名同参的函数也会变成虚函数
派生类中同名同参的函数覆盖了基类中同名同参的虚函数
a)不同作用域
b)同名同参
10、基类对象 =》 派生类对象 X
派生类对象 =》 基类对象 V
基类指针(引用) =》 派生类对象 V
派生类指针(引用) =》 基类对象 X
在语法中,不允许派生类的指针指向基类对象 //派生类有的基类不一定有
允许基类指针指向派生类对象 //基类有的派生类一定有
11、静态的成员变量一定要在类外初始化
二、多态
1、同一接口,不同形态
2、静多态:
3、动多态:
虚函数的机制提供支持
虚函数指针-》虚表-》入口地址
4、虚函数指针 vfptr
优先级最高
5、虚函数表 //虚表也是一个数据vftable
(1)一个类中有一个
(2)存在什么东西 虚函数的地址
(3)生成时间:编译阶段
(4)声明周期:程序开始到程序结束
(5)一个类一张序表
(6).rodata //在只读数据段放着 是数据不是指令
6、哪些函数能成为虚函数
(1)依赖对象
(2)取地址
普通全局函数 X
普通的类成员方法 V
静态的类成员方法 X
inline函数 X
构造函数 X
析构函数 V
7、虚析构
一旦有指针指向派生类对象,就需要写成虚析构
满足同名覆盖的关系
8、多态的发生时机:
(1)指针调用虚函数
(2)对象完整
9、虚表的写入时机
在构造函数第一行代码执行之前
10、虚表的二次写入
一个派生类生成需要两次写入
11、纯虚函数
把接口预留下来而不实现
(1)抽象类
不能实例化对象
当指针或引用
12、C++支持的4种类型强转
(1)const_cast :去掉对象的const属性
(2)static_cast : 编译器认为可以支持的强转,安全性略高
(3)reinterpret_cast :类似C的强转
(4)dynamic_cast : RTTI强制转换 run-time type information
13、虚基类指针 //指向虚基类表
核心的目的是为了找公共的内存块
14、虚基类表放两个偏移
虚基类数据相对于虚基类指针的偏移
15、派生类的内存布局
优先级:非虚基类---》虚基类
虚基类的处理顺序:继承顺序、
16、实现一个不能被继承的类
(1)构造写在私有下 //确定:基类无法向普通类正常使用
(2)加上友元
17、友元关系:
(1)单向性
(2)不可继承
(3)不可传递