【笔记】C++的泛型编程
前言
C++的泛型编程学习笔记
函数模板
定义函数模版
- 定义一个通用的数据类型
- 函数模版可以用
typename
,类模板可以用class
,也可以混用
T
:通用的数据类型,通常为大写字母,通常命名为T
1 | template<typename T> |
1 | template<class T> |
- 先定义模版,然后紧跟着定义函数,组成的就是函数模版的定义
1 | template<typename T> |
调用函数模板
自动类型推倒
- 自动类型推倒要求当传递多个参数时,必须是一致的数据类型
- 不会发生隐式类型转换
1 | template<typename T> |
显示指定类型
- 如果函数没有使用到自定义类型,那么只能使用显示制定类型的方式调用函数模版
- 显示类型需要写在
<>
内 - 会发生隐式类型转换
1 | template<typename T> |
普通函数和函数模板
- 当普通函数和函数模版同时存在时,优先调用普通函数
- 如果要强制调用函数模版,可以使用
<>
实现空模版参数列表的方式
1 | void func() |
函数模板的重载
- 利用具体化的类型实现重载方法,可以优先被调用
1 | Persion |
类模版
定义类模版
- 定义一个通用的数据类型
- 函数模版可以用
typename
,类模板可以用class
,也可以混用
T
:通用的数据类型,通常为大写字母,通常命名为T
1 | template<typename T> |
1 | template<class T> |
- 先定义模版,然后紧跟着定义类,组成的就是类模版的定义
1 | template<class T> |
调用类模版创建对象
- 类模版没有自动类型推导
- 类模版的成员函数,不是一开始就调用,而是在创建时才去创建对象
1 | Persion<int> id(1); |
类模版的默认值
- 类模版的模版参数列表可以有默认值
1 | template<class T> |
类模版中成员函数的调用时机
- 类模版中成员函数并不是编译的时候创建的,而是在调用时才去创建
1 | class Persion1 |
类模版对象作为函数的参数
- 先定义一个类模版
1 | template<class T> |
指定传入类型
1 | void method(Persion<int> &p) |
参数模版化
- 相当于类模版与函数模版组合使用
1 | template<class T> |
将整个类模版化
- 相当于类模版与函数模版组合使用
1 | template<class T> |
类模版与继承
子类直接指定父类模版的类型
1 | template<class T> |
子类也变为模版
子类指定父类的模版
1 | template<class T> |
子类同时指定父类模版和子类的模版
1 | template<class T> |
类模版成员函数类外实现
类模版构造函数的类外实现
1 | template<class T> |
类模版普通函数的类外实现
1 | template<class T> |
查看当前模版的数据类型
1 | template<class T> |
类模版的分文件编写
第一种方法
- 主函数引入源文件
1 |
|
1 |
|
1 |
|
第二种方法
- 主函数引入模版头文件
1 |
|
1 |
|
类模版与友元
全局函数类内实现
1 | template<class T> |
全局函数类外实现
1 | // 声明类 |