1.为什么要引入类模板与函数模板?
在日常的维护中,因为面对不同的数据可能需要执行相同的任务(如比较大小,交换),如果为每一种数据都写一个函数则会浪费大量的精力,引入范式编程这可以解决这个问题。
首先来看一个小例子,对不同的数据类型的两个数进行交换:
范式代码实现:
#include<iostream>
using namespace std;
template <typename T>
T swaping(T &a, T &b) {//标准命名空间下,本身存在一个swap函数,尽量避免名称的冲突
T temp = NULL;
temp = a;
a = b;
b = temp;
return 0;
}
这样的一个函数,可以对任意数据类型的两个参数进行交换。这便是c++所谓的函数模板。
所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
定义函数模板的一般格式:
```
template<类型参数列表>
类型 函数名(形参列表){
剩余语句块
}
_ 模板参数_可以根据我们传递的实参来决定,如果我们传递了两个int给参数类型T const&,那么C++编译器得出结论:每个T都必须正确的匹配,如果此时传递的实参为:max(4, 4.2),则出现编译错误
有3种方法来处理上面的错误:
1、对实参进行强制类型转换,使它们可以互相匹配:
max(static_cast<double>(4), 4.2);
2、显示指定(或限定)T的类型:
max<double>(4, 4.2)
3、指定两个参数可以具有不同的类型
//函数模板的重载
inline int max(const int &a, const int &b) {
return a > b ? a : b;
}
template<typename T>
inline const T& max(T &a, T &b) {
return a > b ? a : b;
}
template<typename T>
inline const T& max(T &a, T &b, T &c) {
return a > (b > c ? b : c) ? a : (b > c ? b : c);
}
//模板类
template<typename T>
class myclass {
public:
myclass() {
cout << "A new instance is created!" << endl;
}
~myclass() {
cout << "destructor is called!" << endl;
}
void change(T a, T b) {
this->_a = a;
this->_b = b;
}
void print() {
cout << this->_a << endl;
cout << this->_b << endl;
}
private:
T _a = 0;
T _b = 0;
};
int main() {
//int a = 3;
//int b = 5;
//char a = 'a';
//char b = 'c';
//swaping(a,b);
//cout << "a==" <<a<< endl;
//cout << "b==" <<b<<endl;
//return 0;
//int a = 3;
//int b = 5;
//int c = 3.4;
//cout<<::max(a, b)<<endl;
//cout << ::max(a, c) << endl;
//cout << ::max(a, b, c) << endl;
myclass<int> test;
test.change(3, 5);
test.print();
myclass<char> test2;
test2.change('a', 'c');
test2.print();
}