要努力,但不要着急,繁花锦簇,硕果累累都需要过程!
前言:
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; };
总结:
有了模板的时候不管是使用模板函数还是使用模板类,大大减轻了代码量,使程序更加简洁,使用起来更加方便
版权归原作者 终为—NULL 所有, 如有侵权,请联系我们删除。