为什么要有模板(templates):当我们需要一个列表(list),列表中元素可能都为X类型也可能都为Y类型,怎么来实现呢?
- 定义基类?可以实现,很多情况下可能不够简明的表达设计思想
- 克隆代码(写一段X关于list的定义,再写一段Y关于list的定义)但是后期无法统一对其管理
- 做一个void*类型的list,缺点是类型不安全
比较好的解决方案就是Templates
函数模板:是一种模板,用来做出函数,比如sort排序函数、swap交换函数等等
类模板:也是一种模板,用来做出类,比如list、map等这些类
函数模板例子:swap函数 ====> swap函数模板
//swap函数 void swap(int& x, int& y) { int temp = x; x = y; y = temp; }
//swap函数模板 template <class T> void swap(T& x, T& y) { T temp = x; x = y; y = temp; }
上边的T可以是int、float这种已有的类型,也可以是用户自己定义的类型。
int i=3; int j = 4; swap(i, j); //这里编译时,编译器会帮我们按照之前templates定义的规则制造一个swap(int,int)函数 float k = 4.5; flaot m = 3.7; swap(k, m); //这里编译器会给我们再做出一个 swap(flaot,flaot)函数 与上边的swap(int,int)是函数重载的关系
注意1:
swap(int,int); //ok swap(double, double); //ok swap(int, double); //error! 并不会把double转为int
注意2:
//函数模板的另一种写法 template <class T> void foo(void) {/*...*/} foo <int>(); //foo(int) foo<float>(); //foo(float)
模板中使用用多个类型:
template <class K, class V> class HashTable { const Value& lookup(const K&) const; const install(const K&, const V&); ... };
模板中使用参数:
template<class T, int bounds=100> //注意这里的bounds变量,有缺省的值,也可以在后边定义类对象的时候赋值 class FixedVector { public: FixedVector(); //... T& operator[] (int); private: T element[bounds]; //fixed size array! }; FixedVector<int, 50> v1; //种出一个50个单元的int的FixedVector FixedVector<int> v2; //默认100个单元
类模板例子:
template <class T> class Vector { public: Vector(int); ~Vector(); Vector(const Vector&); Vector& operator=(const Vector&); T& operator[] (int); private: T* m_elements; int m_size; }; //使用 Vector<int> v1(100); //Vector中的T是int Vector<Complex> v2(256); //Complex 可以是float等类型 v1[20] = 10; v2[20] = v1[20]; //ok if int->Complex 如果int能转换为Complex(向上造型)
T某个成员变量的类型,T做成员函数的返回类型
函数模板遇到继承会怎样?
某个类继承了某个模板种出来的类,什么叫“种”,就是在编译的时候,编译器根据我们定义的模板来给你生成了一段真实的类的代码
template <class A> class Derived:public Vector<A> {...}; //Vector借用上一段代码
目录
- c++(翁恺浙大公开课) 笔记0
- static在cc++中的作用(翁恺c++公开课[28-29]学习笔记)
- c++对象初始化(翁恺c++公开课[10])
- c++构造函数的初始化列表(翁恺c++公开课[13])
- c++继承:公有、私有、保护
- c++子类父类关系(翁恺c++公开课[15-16]学习笔记)
- c++拷贝构造函数(翁恺c++公开课[26-27]学习笔记)
- c++多态性及多态的内部实现(翁恺c++公开课[23-24])
- c++中的运算符重载operator1(翁恺c++公开课[30]学习笔记)
- c++中的运算符重载operator2(翁恺c++公开课[31-33]学习笔记)
- c++模板(翁恺c++公开课[34-35]学习笔记)
- 最好不要在头文件中写函数定义