1. 静态联编和动态联编
1.1多态分类
1.1.1静态多态 函数重载
1.1.2动态多态 虚函数 继承关系
1.2静态联编
1.2.1地址早绑定 编译阶段绑定好地址
1.3动态联编
1.3.1地址晚绑定 ,运行时候绑定好地址
1.4多态
1.4.1父类的引用或指针指向子类对象
2. 多态原理解析
2.1当父类中有了虚函数后,内部结构就发生了改变
2.2内部多了一个 vfprt
2.2.1virtual function pointer 虚函数表指针
2.2.2指向 vftable 虚函数表
2.3父类中结构 vfptr &Animal::speak
2.4子类中 进行继承 会继承 vfptr vftable
2.5构造函数中 会将虚函数表指针 指向自己的虚函数表
2.6如果发生了重写,会替换掉虚函数表中的原有的speak,改为 &Cat::speak
2.7深入剖析,内部到底如何调用
2.8((void()()) ((int*)(int)animal))();
2.9猫吃鱼的函数调用(编译器的调用)
3. 多态案例 – 计算器案例
3.1早期方法 是不利于扩展
3.2开发有原则 开闭原则 – 对扩展开放 对修改关闭
3.3利用多态实现 – 利于后期扩展,结构性非常好,可读性高, 效率稍微低,发生多态内部结构复杂
4. 抽象类 和 纯虚函数
4.1纯虚函数写法 virtual void func() = 0;
4.2抽象类型
4.3抽象类 不可以实例化对象,有虚函数就成为了抽象类
4.4如果类 继承了抽象类, 必须重写抽象类中的纯虚函数
5. 虚析构和纯虚析构
5.1虚析构
5.1.1virtual ~类名() {}
5.1.2解决问题: 通过父类指针指向子类对象释放时候不干净导致的问题
5.2纯虚析构函数
5.2.1写法 virtual ~类名() = 0
5.2.2类内声明 类外实现
5.2.3如果出现了纯虚析构函数,这个类也算抽象类,不可以实例化对象
6. 向上类型转换和向下类型转换
6.1基类转派生类
6.1.1向下类型转换 不安全的
6.2派生类转 基类
6.2.1向上类型转换 安全
6.3如果发生多态
6.3.1总是安全的
6.4父类中如果写了虚函数,而子类没有任何重写,有意义吗?
6.4.1没有意义
7. 函数模板基本使用
7.1.1template<class/typename T> 告诉编译器紧跟代码里出现T 不要报错
7.1.2 mySwap(T &a T &b)类型也需要传入,类型参数化
7.1.3 myswap (a,b) 自动类型推导 按照a b的类型 来替换T
7.1.4 myswap(a,b)显示指定类型
7.2函数模板与普通函数的区别以及调用规则
7.2.1 区别 普通函数可以进行隐式类型转换 模板不可以
7.2.2 调用规则
2.2.1 c++编译器优先考虑普通函数
2.2.2 可以使用空模板实参列表的语法限定编译器只能通过模板匹配
2.2.3模板函数可以像普通函数那样可以被重载
2.2.4 如果函数模板可以产生一个更好的匹配,那么编译器优先选择模板
7.3模板的机制
7.3.1模板并不是万能的,不能通用所有的数据类型
7.3.2模板不能直接调用,生成后的模板函数才可以调用
7.3.3二次编译,第一次编译对模板进行编译,第二次编译对替换T类型后的代码进行编译
7.4模板局限性
7.4.1 模板不能解决所有的类型
7.4.2 如果出现不能解决的类型,可以通过第三代具体化来解决问题
7.4.3 template<>返回值 函数名<具体类型>(参数)
8. 类模板
8.1.1 写法 template <T…>紧跟着是类
8.1.2 与函数模板区别,可以有默认参数类型
8.1.3 函数模板可以自动推导类型,而类模板不可以
8.1.4 成员函数 一开始不会创建出来,而是运行的时候才会创建
8.2 类模板做函数的参数
8.2.1 三种方式
8.2.1.1 显示指定类型
8.2.1.2 参数模板化
8.2.1.3 整体模板化
8.3查看类型名称
8.3.1 cout<<typeid(T).name()<<endl;
8.4当类模板遇到继承
8.4.1 基类如果是模板类,必须让子类告诉编译器 基类中的T到底是什么类型
8.4.2 如果不告诉,那么无法分配内存,编译不过
8.4.3 利用参数列表 class child :public Base
8.5类模板的类外实现成员函数
template <class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout << “姓名:” << this->m_name << endl;
cout << “年龄:” << this->m_age << endl;
}
*8.6类模板的分文件编写问题以及解决
8.6.1 .h .cpp分别声明和实现
8.6.2 但是由于 类模板的成员函数运行阶段才去创建,导致包含.h头文件,不会创建函数的实现,无法解析外部命令
8.6.3 解决方案 保护.cpp文件(不推荐)
8.6.4 不要分文件编写,写到同一个文件中,进行声明和实现,后缀名改为.hpp,约定俗成
*8.7类模板碰到友元函数
8.7.1 友元函数类内实现
8.7.2 friend void printPerson(Person<T1,T2> &p)
8.7.3 友元函数的类外实现
8.7.4 friend void printPerson<>(Person<T1, T2>& p);
//没有<>就是普通函数声明 加上<>就是类模板函数声明
8.7.5 让编译器看到函数,并且看到这个Person类型
template <class T1, class T2>class Person;
template <class T1, class T2>void printPerson(Person<T1, T2>& p);