目录
前言
这篇文章介绍下C++中的模版,包括函数模版和类模版。
1.函数模版
在编程的过程中,编写函数都会考虑将其写成模版函数,编写类的时候都会考虑将其写成类模版,从而减少不必要的重复。
1.函数模版的概念和定义
函数模版是一些列相关函数的模型或者样板,这些函数的源代码形式相同,只是所针对的数据类型不同。
函数模版的声明格式如下:
其中模版形参可以是以下几种形式:
1.typename<参数名>
2.class <参数名>
3.<类型修饰><函数名>
在上面的三种形式中,前两种是等价的。也就是说在声明函数模的时候,关键字typename和class功能一致。使用typename或class声明的参数称为虚拟类型参数;使用类型修饰声明的参数称为常规参数,在形式上与普通的函数参数声明相同。格式中的<函数声明>与一般函数声明类似,只是某些类型修饰符被虚拟类型参数所替代。
例如我们定义个add函数模版,代码如下:
template <class T>
T add(T a, T b) {
return a + b;
}
也可以使用typaneme声明函数模版:
template <typename T>
T add(T a, T b) {
return a + b;
}
在上面的函数模版声明的定义中,T是一个虚拟类型参数,它既可以做函数的返回值类型,又可以做函数的形参的类型,还可以做函数体内变量的类型。类的成员函数也可以声明为函数模版。
2.函数模版的实例化
模版函数值得是函数模版中声明的函数。
定义好函数模版之后,编译系统将依据每一次对模版函数调用时所使用的数据类型生成适当的调用代码,并生成相应的函数版本。编译系统生成函数模版的某个具体版本的过程称为函数模版的实例化,每一个实例就是一个函数的定义。在实例化的过程中,用实参的实际类型代替虚拟类型。
上述的add函数实例化的代码如下:
#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
return a + b;
}
int main(int argc, const char * argv[]) {
int a = 1,b = 2;
int c = add<int>(a,b);
cout<<"整型add函数调用:"<<a<<"\t+\t"<<b<<"\t=\t"<<c<<endl;
float a1 = 1.1,b1 = 2.1;
float c1 = add<float>(a1,b1);
cout<<"float类型调用add函数:"<<a1<<"\t+\t"<<b1<<"\t=\t"<<c1<<endl;
double a3 = 1.22,b3 = 2.222;
double c3 = add<double>(a3,b3);
cout<<"double类型调用add函数:"<<a3<<"\t+\t"<<b3<<"\t=\t"<<c3<<endl;
return 0;
}
2.类模版
1.类模版的概念和定义
类模版指的是一系列相关类的模版或者样板,这些类的成员组成相同,成员函数的源代码形式相同,所不同的只是针对的类型。
类模版声明的格式如下:
2.类模版的实例化
类模版的实例化格式如下
或者
下面的例子中展示了类模版的用法。
#include <iostream>
using namespace std;
template <class T>
class Operates {
T a;
public:
Operates(){}
Operates(T a){
this->a = a;
}
void display(){
cout<<"a="<<a<<endl;
}
T add(T b){
this->a += b;
display();
return this->a;
}
T sub(T b){
this->a -= b;
display();
return this->a;
}
T mult(T b){
this->a *= b;
display();
return this->a;
}
T div(T b){
this->a /= b;
display();
return this->a;
}
};
int main(int argc, const char * argv[]) {
Operates<int> a(10);
int b(10);
a.add(b);
a.sub(b);
a.mult(b);
a.div(b);
return 0;
}
3.示例代码
1.用函数模版实现3个数值按照从最小值到最大值排序的程序
#include <iostream>
using namespace std;
// 模板函数,用于交换两个值
template<typename T>
void mySwap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
// 模板函数,用于对三个数值进行排序
template<typename T>
void sortThreeValues(T& a, T& b, T& c) {
if (a > b) {
mySwap(a, b);
}
if (b > c) {
mySwap(b, c);
}
if (a > b) {
mySwap(a, b);
}
}
int main(int argc, const char * argv[]) {
int x = 1,y = 3,z = 2;
//调用函数排序
sortThreeValues(x, y, z);
cout<<"排序之后的数据:\t"<<x<<"\t"<<y<<"\t"<<z<<endl;
return 0;
}
2.利用函数模版设计一个求数组元素中和的函数,并检验
#include <iostream>
using namespace std;
// 模板函数,用于交换两个值
template<typename T>
void mySwap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
// 模板函数,用于对三个数值进行排序
template<typename T>
void sortThreeValues(T& a, T& b, T& c) {
if (a > b) {
mySwap(a, b);
}
if (b > c) {
mySwap(b, c);
}
if (a > b) {
mySwap(a, b);
}
}
template <typename T,size_t N>
T sumArray(const T (&arr)[N]) {
T sum = 0;
for (size_t i = 0; i< N ; i++) {
sum += arr[i];
}
return sum;
}
int main(int argc, const char * argv[]) {
// 定义一个整型数组
int intArray[] = {1, 2, 3, 4, 5};
// 计算整型数组的和
int intSum = sumArray(intArray);
cout << "Sum of integers: " << intSum << endl;
// 定义一个双精度浮点型数组
double doubleArray[] = {1.1, 2.2, 3.3, 4.4, 5.5};
// 计算双精度浮点型数组的和
double doubleSum = sumArray(doubleArray);
cout << "Sum of doubles: " << doubleSum << endl;
return 0;
}
3.重载上题中的函数模版,使其能够进行两个数组的求和
#include <iostream>
using namespace std;
// 函数模板,用于计算数组元素的和
template<typename T, size_t N>
T sumArray(const T (&arr)[N]) {
T sum = 0;
for (size_t i = 0; i < N; ++i) {
sum += arr[i];
}
return sum;
}
// 重载函数模板,用于计算两个数组对应元素的和
template<typename T, size_t N>
T sumArray(const T (&arr1)[N], const T (&arr2)[N]) {
T sum = 0;
for (size_t i = 0; i < N; ++i) {
sum += arr1[i] + arr2[i];
}
return sum;
}
int main(int argc, const char * argv[]) {
// 定义两个整型数组
int intArray1[] = {1, 2, 3, 4, 5};
int intArray2[] = {6, 7, 8, 9, 10};
// 计算两个整型数组的和
int intSum = sumArray(intArray1, intArray2);
cout << "Sum of integers: " << intSum << endl;
// 定义两个双精度浮点型数组
double doubleArray1[] = {1.1, 2.2, 3.3, 4.4, 5.5};
double doubleArray2[] = {6.6, 7.7, 8.8, 9.9, 10.0};
// 计算两个双精度浮点型数组的和
double doubleSum = sumArray(doubleArray1, doubleArray2);
cout << "Sum of doubles: " << doubleSum << endl;
return 0;
}