要努力,但不要着急,繁花锦簇,硕果累累都需要过程!
目录
前言:
1.泛型编程
2.模板
2.1模板的概念及分类:
2.2函数模板:
2.3类模板
总结:
前言:
C++语言既要兼容C语言,又在很多地方做了升级改变,引入了许多新的东西,补充C语言的不足,本章介绍的是C++针对C语言的不足,引入了一个新的东西——模板,接下来详细介绍一下什么是模板,模板有什么用。
1.泛型编程
实现两个数的交换:
void Swap(int* left, int* right)
{
int temp = *left;
*left = *right;
*right = temp;
}
void Swap(double* left, double* right)
{
double temp = *left;
*left = *right;
*right = temp;
}
void Swap(char* left, char* right)
{
char temp = *left;
*left = *right;
*right = temp;
}
在C语言中实现两个数的交换,我们需要对不同的数据类型写不同的函数来实现,这种方式虽然能够实现两个数的交换,但是种过程比较繁琐,那有没有一种东西可以只写一个函数,就能够实现对不同的数据类型的两个数进行交换?C++中引入的模板就是针对这种情况而进行设计的。?
泛型编程:编写与类型无关的通用代码,模板是泛型编程的基础
2.模板
2.1模板的概念及分类:
举个例子:
?模板就如图中的模具一样,有需要的时候只需要使用模具复刻一份出来就行了
模板的分类:
在C++语言中模板分为函数模板和类模板:
2.2函数模板:
1.概念:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
2.函数模板的格式:
template<typename T>
template 和 typename 是C++中定义模板引入的关键字,T是任意的。
注:typename可以用calss替代
交换两个数现在就可以用模板来实现了:
?3.函数模板实现的原理:
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器,当实现两个数交换的时候编译自动推导类型生成相应的函数
4.函数模板的实例化:
1.隐式实例化:让编译器根据实参推演模板参数的实际类型
template<typename T>
void Swap(T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
int main()
{
int a = 10;
int b = 20;
double c = 20.0;
double d = 10.0;
Swap(a, b);
Swap(c, d);
return 0;
}
注:在隐式实例化的过程中,针对上图这种情况编译器在推导的时候不确定需要推导为int还是double,因此会报错
解决方法:需要进行强转:
?注:强制转化的时候会生成一个临时变量,该临时变量具有常性,因此在用引用的时候需要用const修饰
2.显示实例化:
?5.函数模板的匹配原则:
编译器允许一个同名的非模板函数和模板函数同时存在
注:当非模板函数和模板函数同时存在的时候,编译器会优先使用非模板函数?
2.3类模板
类模板实例化与函数模板实例化不同,函数模板在传递类型的会自动推导,而类模板没有机会进行推导,因此类模板实例化需要显示实例化
template<typename T>
class Stack
{
public:
Stack(int capacity = 4)
{
cout << "Stack(int capacity = )" <<capacity<<endl;
_a = (T*)malloc(sizeof(T)*capacity);
if (_a == nullptr)
{
perror("malloc fail");
exit(-1);
}
_top = 0;
_capacity = capacity;
}
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
void Push(const T& x)
{
// ....
// 扩容
_a[_top++] = x;
}
private:
T* _a;
int _top;
int _capacity;
};
总结:
有了模板的时候不管是使用模板函数还是使用模板类,大大减轻了代码量,使程序更加简洁,使用起来更加方便
|