CPP语法(六)——函数模板

CPP语法 六---函数模板

    • [一、 模板](#一、 模板)
      • [1.1 函数模板](#1.1 函数模板)
      • [1.2 重载函数模板](#1.2 重载函数模板)
      • [1.3 类模板](#1.3 类模板)
        • [1.3.1 简单类模板](#1.3.1 简单类模板)
        • [1.3.2 默认模板参数](#1.3.2 默认模板参数)
        • [1.3.3 为具体类型的参数提供默认值](#1.3.3 为具体类型的参数提供默认值)
        • [1.3.4 有界数组模板](#1.3.4 有界数组模板)
      • [1.4 模板的使用](#1.4 模板的使用)
        • [1.4.1 定制模板类](#1.4.1 定制模板类)
        • [1.4.2 定制类模板成员函数](#1.4.2 定制类模板成员函数)

一、 模板

模板是c++的高级特性,分为函数模板和类模板。标准模板库(STL)

模板只作用于其下方的类或函数

1.1 函数模板

函数模板定义

cpp 复制代码
template <类型形式参数表> 返回类型 函数名(形式参数表)
{
    ...  //函数体
}

template <class T>
void fun(T t)
{
    ...		//函数实现
}

template <class type>
type Sum(type xvar,type yvar)
{
    return xvar + yvar;
}

//隐式
int result = Sum(10,20);
doouble result = Sum(10.0,20.0);

//显示
int result = Sum<int>(10,20);
double result = Sum<double>(10.0,20.0);

如果两个参数类型不一样,会报错

template 为关键字,表示定义一个模板,尖括号<>表示模板参数。

模板参数主要有两种:一种是模板类型参数,另一种是模板非类型参数。

1.2 重载函数模板

整型数和浮点数编译器可以直接比较,所以使用函数模板也能直接比较。

cpp 复制代码
#include <iostream >
#include <string >
using namespace std;
template<class Type>
Type min(Type a,Type b)//定义函数模板
{
	if(a < b)
		return a;
	else
		return b;
}
char * min(char * a,char * b)// 重载函数模板
{
	if(strcmp(a,b))
		return b;
	else 
		return a;
}
void main ()
{
	cout << "最小值:" << min(10,1) << endl;
	cout << "最小值:" << min('a','b') << endl;
	cout << "最小值:" << min("hi","mr") << endl;
}

1.3 类模板

类模板代表一族类,是用来描述通用数据类型或处理方法的机制,它使类中的数据成员和成员函数的参数或返回值可以取任意数据类型。类模板可以说是用类生成类,减少类的定义数量。

类模板声明:

cpp 复制代码
template <类型形式参数表> class 类模板名
{
    ...		//类模板体
};

类模板成员函数定义:

cpp 复制代码
template <类型形式参数表>
返回类型 类模板名 <类型名>::成员函数名(形式参数列表)
{
    	... //函数体
}

其中类型形式参数表中的 参数也可以是其他模板。

cpp 复制代码
template <template <class A> class B>
class cBase
{
    private:
    B<int> m_n;
}

类模板也可以继承:

cpp 复制代码
template <class T>
class CDerived public T
{
	public:
	CDrived();
};
template <class T>
CDerived<T>::CDerived():T()
{
    cout<<""<<endl;
}
void main()
{
    CDerived<CBase1> D1;
    CDerived<CBase1> D1;
}
1.3.1 简单类模板
cpp 复制代码
#include <iostream>
using namespace std;
template<class T1,class T2>
class MyTemplate
{
	T1 t1;
	T2 t2;
	public:
		MyTemplate(T1 tt1,T2 tt2)
		{t1 =tt1, t2=tt2;}
		void display()
		{ cout << t1 << ' ' << t2 << endl;}
};
void main()
{
	int a=123;
	double b=3.1415;
	MyTemplate<int ,double> mt(a,b);
	mt.display();
}
1.3.2 默认模板参数
cpp 复制代码
#include <iostream>
using namespace std;
template <class T1,class T2 = int>
class MyTemplate
{
	T1 t1;
	T2 t2;
public:
	MyTemplate(T1 tt1,T2 tt2)
	{t1=tt1;t2=tt2;}
	void display()
	{
 		cout<< t1 << ' ' << t2 << endl;
	}
};
void main()
{
	int a=123;
	double b=3.1415;
	MyTemplate<int ,double> mt1(a,b);
	MyTemplate<int> mt2(a,b);
	mt1.display();
	mt2.display();
}
1.3.3 为具体类型的参数提供默认值
cpp 复制代码
#include <iostream>
using namespace std;
template<class T1,class T2,int num= 10 >
class MyTemplate
{
	T1 t1;
	T2 t2;
	public:
		MyTemplate(T1 tt1,T2 tt2)
		{t1 =tt1+num, t2=tt2+num;}
		void display()
		{ cout << t1 << ' ' << t2 <<endl;}
};
void main()
{
	int a=123;
	double b=3.1415;
	MyTemplate<int ,double> mt1(a,b);
	MyTemplate<int ,double ,100> mt2(a,b);
	mt1.display();
	mt2.display();
}
1.3.4 有界数组模板

在模板中想要获取下标值,需要重载数组下标运算符 [ ] ,然后使用模板类实例化数组,就可以进行下标越界检测。例如:

cpp 复制代码
#include <cassert>
template <class T,int b>
class Array
{
    T& operator[](int sub)
    {
        assert(sub >= 0 && sub < b);
    }
}

比较模板重载

cpp 复制代码
#include "stdafx.h"
#include <iostream>

/*
  定义一个能够求的模板函数,并重载该模板函数,使其可以比较字符串的大小。
*/

using namespace std;

template<class T>
T max(T a, T b) {
  return a>b?a:b;
}

const char * max(const char *a, const char * b) {
  if(strcmp(a,b)){
    return b;
  }
  else {
    return a;
  }
}

int main(int argc, char* argv[])
{
  cout << "最大值:" << max(10,1) << endl;
  cout << "最大值:" << max('a','b') << endl;
  cout << "最大值:" << max("hi","mr") << endl;
  return 0;
}

1.4 模板的使用

定义模板类后如果想扩展模板新类的功能,需要对类模板进行覆盖,使模板类能够完成特殊功能。覆盖操作可以针对整个类模板、部分类模板以及类模板的成员函数,这种覆盖操作称为定制。

1.4.1 定制模板类

定制一个类模板,覆盖类模板中定义的 所有 成员。

cpp 复制代码
#include <iostream>
using namespace std;
class Date
{
	int iMonth,iDay,iYear;
	char Format[128];
public:
	Date(int m=0,int d=0,int y=0)
	{
		iMonth=m;
		iDay=d;
		iYear=y;
	}
	friend ostream& operator<<(ostream& os,const Date t)
	{
		cout << "Month: " << t.iMonth << ' ' ;
		cout << "Day: " << t.iDay<< ' ';
		cout << "Year: " << t.iYear<< ' ' ;
		return os;
		
	}
	void Display()
	{
		cout << "Month: " << iMonth;
		cout << "Day: " << iDay;
		cout << "Year: " << iYear;
		cout << endl;
	}
};

template <class T>
class Set
{
	T t;
	public:
		Set(T st) : t(st) {}
		void Display()
		{
			cout << t << endl;
		}
};
class Set<Date>
{
	Date t;
public:
	Set(Date st): t(st){}
	void Display()
	{
		cout << "Date :" << t << endl;
	}
};
void main()
{
	Set<int> intset(123);
	Set<Date> dt = Date(1,2,3);	//还可以写成这样 Set<Date> dt(Date(1,2,3));
	intset.Display();
	dt.Display();
}
1.4.2 定制类模板成员函数

定制一个类模板,覆盖类模板中指定的成员

cpp 复制代码
#include <iostream>
using namespace std;
class Date
{
	int iMonth,iDay,iYear;
	char Format[128];
public:
	Date(int m=0,int d=0,int y=0)
	{
		iMonth=m;
		iDay=d;
		iYear=y;
	}
	friend ostream& operator<<(ostream& os,const Date t)
	{
		cout << "Month: " << t.iMonth << ' ' ;
		cout << "Day: " << t.iDay<< ' ';
		cout << "Year: " << t.iYear<< ' ' ;
		return os;
		
	}
	void Display()
	{
		cout << "Month: " << iMonth;
		cout << "Day: " << iDay;
		cout << "Year: " << iYear;
		cout << std::endl;
	}
};
template <class T>
class Set
{
	T t;
	public:
		Set(T st) : t(st) {}
		void Display();
};
template <class T>
void Set<T>::Display()
{
	cout << t << endl;
}
void Set<Date>::Display()
{
	cout << "Date: " << t << endl;
}
void main()
{
	Set<int> intset(123);
	Set<Date> dt =Date(1,2,3);
	intset.Display();
	dt.Display();
}
相关推荐
南东山人31 分钟前
一文说清:C和C++混合编程
c语言·c++
Ysjt | 深3 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
ephemerals__3 小时前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
Microsoft Word4 小时前
c++基础语法
开发语言·c++·算法
一只小小汤圆4 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
legend_jz4 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE4 小时前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
ö Constancy5 小时前
c++ 笔记
开发语言·c++
fengbizhe5 小时前
笔试-笔记2
c++·笔记