c++学习之五

本文详细探讨了C++中的多态性,包括静态联编与动态联编,重点阐述了虚函数和多态原理,如虚函数表和类型转换。同时,介绍了抽象类、纯虚函数及虚析构函数的概念和作用。此外,还讲解了函数模板和类模板的使用,以及模板的局限性和解决策略。最后,讨论了类模板在继承和友元函数中的应用及其注意事项。
摘要由CSDN通过智能技术生成

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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li_ao527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值