0%
前言
C++泛型编程学习笔记
函数模板
定义函数模版
- 定义一个通用的数据类型
- 函数模版可以用
typename
,类模板可以用class
,也可以混用
T
:通用的数据类型,通常为大写字母,通常命名为T
- 先定义模版,然后紧跟着定义函数,组成的就是函数模版的定义
1 2 3 4 5 6 7
| template<typename T> T func(T &t) { ... return t; }
|
调用函数模板
自动类型推倒
- 自动类型推倒要求当传递多个参数时,必须是一致的数据类型
- 不会发生隐式类型转换
1 2 3 4 5 6 7
| template<typename T> void func(T t1, T t2) { ... }
func(1, 1);
|
显示指定类型
- 如果函数没有使用到自定义类型,那么只能使用显示制定类型的方式调用函数模版
- 显示类型需要写在
<>
内
- 会发生隐式类型转换
1 2 3 4 5 6 7
| template<typename T> void func() { ... }
func<int>();
|
普通函数和函数模板
- 当普通函数和函数模版同时存在时,优先调用普通函数
- 如果要强制调用函数模版,可以使用
<>
实现空模版参数列表的方式
1 2 3 4 5 6 7 8 9 10 11 12 13
| void func() { ... }
template<typename T> void func() { ... }
func<>();
|
函数模板的重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Persion { public: Persion() {} }
template<typename T> void func(T t) { ... }
template<> void func(Persion num) { ... }
Persion p(); func(p);
|
类模版
定义类模版
- 定义一个通用的数据类型
- 函数模版可以用
typename
,类模板可以用class
,也可以混用
T
:通用的数据类型,通常为大写字母,通常命名为T
- 先定义模版,然后紧跟着定义类,组成的就是类模版的定义
1 2 3 4 5 6 7 8 9
| template<class T> class Persion { private: T id; public: Persion(T id); this->id = id; };
|
调用类模版创建对象
- 类模版没有自动类型推导
- 类模版的成员函数,不是一开始就调用,而是在创建时才去创建对象
类模版的默认值
1 2 3 4 5 6 7 8 9 10 11 12 13
| template<class T> class Persion { private: T id; public: Persion(T id = int) { this->id = id; } };
Persion<> id(1);
|
类模版中成员函数的调用时机
- 类模版中成员函数并不是编译的时候创建的,而是在调用时才去创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Persion1 { public: void method1() {} };
class Persion2 { public: void method2() {} };
template<class T> class Persion { private: T obj; public: void method1() { obj.method1(); } void method2() { obj.method2(); } };
void main() { Persion<Persion1> p1; p1.method1(); Persion<Persion2> p2; p2.method2(); }
|
类模版对象作为函数的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| template<class T> class Persion { private: T t; public: Persion(T t) { this->t = t; } void method() { ... } };
|
指定传入类型
1 2 3 4 5 6 7 8 9 10
| void method(Persion<int> &p) { p.method(); }
void main() { Persion<int>p(1); method(p); }
|
参数模版化
1 2 3 4 5 6 7 8 9 10 11
| template<class T> void method(Persion<T> &p) { p.method(); }
void main() { Persion<int>p(1); method(p); }
|
将整个类模版化
1 2 3 4 5 6 7 8 9 10 11
| template<class T> void method(T &p) { p.method(); }
void main() { Persion<int>p(1); method(p); }
|
类模版与继承
子类直接指定父类模版的类型
1 2 3 4 5 6 7 8 9 10
| template<class T> class Father { T t; };
class Son:public Father<int> { ... };
|
子类也变为模版
子类指定父类的模版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| template<class T> class Father { T t; };
template<class T> class Son:public Father<T> { T t; };
void main() { Son<int> s; }
|
子类同时指定父类模版和子类的模版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| template<class T> class Father { T t; };
template<class T_father, class T_son> class Son:public Father<T_father> { T_son t_son; };
void main() { Son<int, int> s; }
|
类模版成员函数类外实现
类模版构造函数的类外实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| template<class T> class Persion { private: T t; public: Persion(T t); };
template<class T> Persion<T>::Persion(T t) { this->t = t; }
|
类模版普通函数的类外实现
1 2 3 4 5 6 7 8 9 10 11 12 13
| template<class T> class Persion { private: T t; public: void method(); };
void Persion<T>::method() { ... }
|
查看当前模版的数据类型
1 2 3 4 5
| template<class T> void method(T t) { typeid(T).name(); }
|
类模版的分文件编写
第一种方法
Persion.h
1 2 3 4 5 6 7 8 9 10 11 12
| #pragma once #include <iostream> using namespace std;
template<class T> class Persion { private: T t; public: Persion(T t); };
|
Persion.cpp
1 2 3 4 5 6 7
| #include "Persion.h"
template<class T> Persion<T>::Persion(T t) { this->t = t; }
|
main.cpp
1 2 3 4 5 6
| #include "Persion.cpp"
void main() { Persion<int> p(1); }
|
第二种方法
Persion.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #pragma once #include <iostream> using namespace std;
template<class T> class Persion { private: T t; public: Persion(T t); };
template<class T> Persion<T>::Persion(T t) { this->t = t; }
|
main.cpp
1 2 3 4 5 6
| #include "Persion.hpp"
void main() { Persion<int> p(1); }
|
类模版与友元
全局函数类内实现
1 2 3 4 5 6 7 8
| template<class T> class Persion { friend void method(Persion<T> p) { ... } };
|
全局函数类外实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| template<class T> class Persion;
template<class T> void method(Persion<T> p) { ... }
template<class T> class Persion { friend void method<>(Persion<T> p); };
|
完成
参考文献
哔哩哔哩——黑马程序员