一、概述
用类模板来实例化一个特定的类。
编译器不能为类模板推断参数类型,所以为了使用类模板,我们必须在类模板名后边用<>来提供额外的信息,这些信息就是对应模板参数列表里面的这些参数。实现同一套代码,可以应付不同的数据类型,这样就显得精简多了。
例如:vector<int>,vector<double>,vector<string>等等。
二、类模板的定义
//template<typename 形参名1,typename 形参名2,…typename 形参名n>
// class 类名
// {
// }
实例化类模板的时候,必须要有类的全部信息,包括类模板中成员函数的函数体
创建一个myvector.h
#ifndef myvector_hpp
#define myvector_hpp
#include <stdio.h>
#include <istream>
#include <iostream>
//定义模板
template<typename T>
class myvector
{
public:
typedef T* myiterator;//迭代器
public:
myvector();//构造函数
//myvector& operator=(const myvector&);//赋值运算符重载,在模板内部使用模板名,不需要提供模板参数
myvector<T>& operator=(const myvector<T>&);
public:
myiterator mybegin();
myiterator myend();
public:
void myfunc() {};//在类模板定义的成员函数会被隐式声明为inline函数
};
#endif
int main() {
myvector<int> temp1; //这个时候编译器生产了一个具体的类
myvector<double> temp2;
}
myvector是类模板名,他不是一个类名,类模板是用来实例化类(类型)用的。
所以 myvector,myvector才是类型名(实例化了的类型)。
所以,一个实例化了的类型总会用尖括号<>包含模板参数。
三、类模板的成员函数
- 类模板成员函数,可以写在类模板定义中{},那么这种写在类模板定义的成员函数会被隐式声明为inline函数。
- 类模板一旦被实例化之后,那么这个模板的每个实例都会有自己版本的成员函数。
所以 类模板的成员函数具有和这个类模板相同的模板参数(这句话的核心意思:类模板的成员函数是有模板参数的)
如果你要把类模板成员函数的定义(函数体)写在类模板定义的外边,那么这个成员函数的模板参数就体现出来了。
定义在类模板之外的成员函数必须以关键字template开始,后面接类模板参数列表
同时,在类名后面要用尖括号<>把模板参数列表里面的所有的模板参数名列出来,如果是多个模板参数用,分隔
一个类模板虽然可能有很多成员函数,但是,当你实例化模板之后,如果你后续没有使用到某个成员函数的话,则这个成员函数不会被实例化。
说白了,就是一个实例化的模板,它的成员函数只有在使用的时候才会被实例化。
四、模板类名字的使用
#ifndef myvector_hpp
#define myvector_hpp
#include <stdio.h>
#include <istream>
#include <iostream>
//定义模板
template<typename T>
class myvector
{
public:
typedef T* myiterator;//迭代器
public:
myvector();//构造函数
//myvector& operator=(const myvector&);//赋值运算符重载,在模板内部使用模板名,不需要提供模板参数
myvector<T>& operator=(const myvector<T>&);
public:
myiterator mybegin();
myiterator myend();
public:
void myfunc(); //{};//在类模板定义的成员函数会被隐式声明为inline函数
};
//普通成员函数
template<typename T>
void myvector<T>::myfunc()
{
return;
}
//构造函数
template<typename T>
myvector<T>::myvector()
{
}
template<typename T>
myvector<T>& myvector<T>::operator=(const myvector<T>& myvector)
{
return *this;
}
#endif
五、非类模板参数
#ifndef myarray_hpp
#define myarray_hpp
#include <stdio.h>
#include <istream>
#include <iostream>
using namespace std;
template<typename T, int size = 10>//size非类型模板参数
class myarray
{
public:
myarray()
{
};
myarray(T arr)
{
this->arr[0] = arr;
}
public:
void myfunc();
private:
T arr[size];
};
template<typename T, int size>
void myarray<T, size>::myfunc()
{
cout << size << endl;
cout << arr[0] << endl;
}
#endif
#include <iostream>
#include "myvector.h"
#include "myarray.h"
using namespace std;
int main()
{
myarray<int,100> temparray1;
temparray1.myfunc();
return 1;
}
非类型模板参数也是有限制的
- 浮点型不能作为非类型模板参数 比如float double
- 类类型一般也不允许做非类型模板参数