C++12 Template
**
- 要他们有共同的基类(做不到)
- 克隆代码(保证了类型安全,不好管理,难以维护)
- 无类型list(不安全,任何东西都能放进去,取出来的时候怎么知道是x还是y?)
- 用Template
**
- 类型成为template的参数
- 函数模板/类模板
如上图,C++好处就是可以用reference直接交换值。上面只能交换Int,如果想交换 other type 比如string之类的,把它做成下图函数模板。
- T是可以换的,只是参数。
- 在template关键字下面的那个东西就称为template
- 在函数模板里面可以使用T来代表一个类型
template实际上是一个申明而不是定义。当C++compile看到template代码以后,什么也不干, 只是把template那些代码记下来。instantiation(实例化)
- 上图:遇到第一个swap,上上面已经定义了int的swap,会直接做
- 遇到第二个swap, 给了两个float, float到int的自动转换是做不了的。
- 又因为定义了swap的模板, 所以会自动在这里帮你种处一个swap函数来。那个swap函数接受float作为输入的。
- 所以最终代码里面出现了一个swap(float, flaoat), 这个函数与原来的 swap(int, int) ooverloaded,
- 这就是模板的作用,模板就是告诉编译器:你要怎样做出我要的函数来。。
oveloaded函数:可以参数个数相同,参数类型不同。
因为template里面写的是swap(T& x, T& y), 意味着x和y是完全相同的类型,所以swap 它们是做不到的。
还有一种情况如上图
- foo函数参数表里面没有用到T
- 所以这个时候想要种一个你那个类型的foo出来就要像最后两行那样写
- foo(); foo();
##对于类来说的template
第一二行说明Vector是一个template。
- Vector意味着要用int来做那里面的T
- 上图,每一个函数都是函数模板如下图
类模板里面每一个函数都是函数模板,并且在这些函数名称里面那个类的名字中间也要加上尖括号,如上图的Vector(类的名字)::Vector(int size)
Vector(矢量,向量,载体)
**圆括号里面数字是构造函数参数,所以v1是个int的Vector, 把int变成complex的方法只有一种,那就是complex有一个构造函数,那个构造函数是一个int作为输入的, **
这种类模板的方法:需要把实际类型的名字用尖括号放在模板后面。
Key其实是一个将来要替换掉的类型,
这个Vector里面每一个单元都是一个Vector, 第二个Vector里面每一个单元都是一个double的指针。
这个class的意思是在说T是一种类型, Int 的意思是bounds是一种整数。
交给sort函数的那个T,必须实现了<这个运算符,不然没法sort东西的。
arr[j]实际上是那个Vector的一个overloaded operator index(重载运算符索引),arr[j]的类型是T, 所以这里是swap T, 但是程序编译到这里不会做出一个 swap T的函数来, 因为这是declaration。compiler对declartion只做一件事,就是记录下来。有点像#include
出现template以后C++的编译一定是多遍扫描的, 一遍做不过来了。
< 意味着T那种类型需要有overloaded operator less than ,如果没有会编译出错
template里面可以有多个参数, template,class是关键字,T/key这些不是关键字,可以随便换。上图出现的key和Vakue都是以后要替换掉的。
Template与继承
上图,我们做了一个类模板,这个类模板里面的类将来种的时候,种下去的每一个类都是Base类的子类。
template和template之间是不能做继承的, 继承的是将来去种这个Derive类的时候, 要把List of A种出来, 如果A有,那就有了如果没有还要去把List of A给种出来。然后才能去做继承,所以实际上不是模板继承,而是模板里出现了继承的东西。可能是某个类继承了某个模板种出来的类,
SupervisorGroup是一个实际的类, 它继承的是用List这个模板种出来的List<Employee>这么一个类的子类*
只要前面没有template就是类,不是模板。
第一行:种了一个50个单元的int的FixedVector,
第三行:种了100个单元的FixedVector
v2和v3不是同一个类型的, 编译器同一时间只做一个编译单元。