1.一些类主要用于存储和组织数据元素,类中数据组织的方式和数据元素的具体类型无关,只关注需要实现的功能,如数组类、链表类、Stack类、Queue类
2.类模板的应用
(1)只能显示指定具体类型,无法自动推导
(2)使用具体类型<Type>定义对象
3.编译器对类模板的处理方式和函数模板相同
(1)从类模板通过具体类型产生不同的类
(2)在声明的地方对类模板代码本身进行编译
(3)在使用的地方对参数替换后的代码进行编译
#include <iostream>
#include<string>
using namespace std;
template <typename T>
class Operator {
public:
T add(T a, T b) {
return a + b;
}
T minus(T a, T b) {
return a - b;
}
T multiply(T a, T b) {
return a * b;
}
T divide(T a, T b) {
return a / b;
}
};
int main() {
Operator<int> op1;
cout << op1.add(1, 2) << endl;
Operator<string> op2;
cout << op2.add("ab", "cd") << endl;
// cout << op2.minus("ab", "cd") << endl; 报错,因为string类型没有减法运算
return 0;
}
所以要重载string类型的减法运算符
#include <iostream>
#include<string>
using namespace std;
template <typename T>
class Operator {
public:
T add(T a, T b) {
return a + b;
}
T minus(T a, T b) {
return a - b;
}
T multiply(T a, T b) {
return a * b;
}
T divide(T a, T b) {
return a / b;
}
};
string operator- (const string& a, const string& r) {
return "Minus";
}
int main() {
Operator<int> op1;
cout << op1.add(1, 2) << endl; //3
Operator<string> op2;
cout << op2.add("ab", "cd") << endl; //abcd
cout << op2.minus("ab", "cd") << endl; //Minus
return 0;
}
4.类模板的工程应用
(1)类模板必须在头文件中定义
(2)类模板不能分开实现在不同的文件中
(3)类模板外部定义的成员函数需要加上模板<>声明
Complex.h
#pragma once
//声明成员函数
template <typename T>
class Operator {
public:
T add(T a, T b);
T minus(T a, T b);
T multiply(T a, T b);
T divide(T a, T b);
};
//定义成员函数
template <typename T>
T Operator<T>::add(T a, T b) {
return a + b;
}
template <typename T>
T Operator<T>::minus(T a, T b) {
return a - b;
}
template <typename T>
T Operator<T>::multiply(T a, T b) {
return a * b;
}
template <typename T>
T Operator<T>::divide(T a, T b) {
return a / b;
}
main.cpp
#include <iostream>
#include<string>
using namespace std;
#include "Complex.h"
int main() {
Operator<int> op1;
cout << op1.add(1, 2) << endl; //3
cout << op1.minus(1, 2) << endl; //-1
cout << op1.multiply(1, 2) << endl; //2
cout << op1.divide(1, 2) << endl; //0
}
5.类模板可以定义任意多个不同的类型参数
类模板可以被特化:当通用类模板对某个 / 某些特定类型不适用、需要定制逻辑时,为这些类型单独编写专属的模板实现。
(1)指定类模板的特定实现
(2)部分类型参数必须显示指定
(3)根据类型参数分开实现类模板
部分特化:用特定规则约束类型参数
完全特化:完全显示指定类型参数
部分特化:
#include <iostream>
#include<string>
using namespace std;
template <typename T1, typename T2>
class Test {
public:
void add(T1 a, T2 b) {
cout << "void add(T1 a, T2 b)" << endl;
cout << a + b << endl;
}
};
template <typename T>
class Test<T, T> { //当Test类模板的两个类型参数完全相同时,使用这个实现
public:
void add(T a, T b) {
cout << "void add(T a, T b)" << endl;
cout << a + b << endl;
}
};
int main() {
Test<int, float> t1;
t1.add(1, 2.5);
Test<long, long> t2;
t2.add(5, 5);
return 0;
}
运行结果:
void add(T1 a, T2 b)
3.5
void add(T a, T b)
10
完全特化:
-
完全特化 表示显示指定类型参数 ,模板声明只需写成template<>,并在类名右侧指定参数
#include <iostream>
#include<string>
using namespace std;template <typename T1, typename T2>
class Test {
public:
void add(T1 a, T2 b) {
cout << "void add(T1 a, T2 b)" << endl;
cout << a + b << endl;
}
};
template <typename T1,typename T2>
class Test<T1*, T2*> {
public:
void add(T1* a, T2* b) {
cout << "void add(T1 * a, T2 * b)" << endl;
cout << *a + *b << endl;
}
};//完全特化
template< >
class Test<void*, void* > {
public:
void add(void* a, void* b) { //当T1==void* 并且 T2==void* 时
cout << "void add(void* a, void* b)" << endl;
cout << "Error..." << endl;
}
};
int main() {
Test<int, float> t1;
t1.add(1, 2.5);Test<void*, void*> t3; t3.add(NULL, NULL); Test<int*, double*> t4; int a = 1; double b = 0.1; t4.add(&a, &b); return 0;}
运行结果:
void add(T1 a, T2 b)
3.5
void add(void* a, void* b)
Error...
void add(T1 * a, T2 * b)
1.1
6.类模板特化注意事项
(1)特化只是模板的分开实现,本质上是同一个类模板
(2)特化类模板的使用方式是统一的,必须显示指定每一个类型参数
类模板特化和重定义的区别?
重定义:一个类模板和一个新类,或者两个类模板;
特化:以统一的方式使用类模板和特化类,编译器自动优先选择特化类
函数模板也可以特化,但只能完全特化
#include <iostream>
#include<string>
using namespace std;
////完全特化
//template< >
//class Test<void*, void* > {
//public:
// void add(void* a, void* b) { //当T1==void* 并且 T2==void* 时
// cout << "void add(void* a, void* b)" << endl;
// cout << "Error..." << endl;
// }
//};
//对上面的特化的重定义
class Test_Void {
public:
void add(void* a, void* b) {
cout << "void add(void* a, void* b)" << endl;
}
};
//函数模板
template<typename T>
bool Equal(T a, T b) {
cout << "bool Equal(T a, T b)" << endl;
return a == b;
}
//函数模板的完全特化
template<>
bool Equal<double>(double a, double b) {
const double delta = 0.00000000000001;
double r = a - b;
cout << "bool Equal<double>(double a, double b)" << endl;
return (-delta < r) && (r < delta);
}
int main() {
//Test<void*, void*> t3;
Test_Void t3;
t3.add(NULL, NULL);
cout << Equal(1, 1) << endl;
cout << Equal<double>(0.001, 0.001) << endl; //由于浮点数在内存中的表示是不精确的,所以不能用==比较,所以要用函数的完全特化
return 0;
}
运行结果:
void add(void* a, void* b)
bool Equal(T a, T b)
1
bool Equal<double>(double a, double b)
1