设为首页 加入收藏

TOP

c++学习笔记——模板和IO(一)(一)
2023-07-23 13:39:14 】 浏览:263
Tags:习笔记

前言

本文主要作为本人学习C\C++历程的的一种记录,以期望通过这种方式加深对知识点的记忆,查漏补缺。如有写得不对的地方,欢迎大家批评改正。

模板概论

模板是泛型编程的基础,是创建泛型类或函数的蓝图或公式。
C++提供了两种模板机制:函数模板和类模板。函数模板,实际上是建立了一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。类模板和函数模板的定义和使用类似。
下面开始逐一介绍C++模板的应用。

函数模板

定义函数模板

点击查看代码
template<class T>	//注意:T代表泛型的数据类型,不是只能写T,
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

也可以这样定义函数模板

点击查看代码
template<typename T>
void mySwap(T& a,T& b)
{

}

怎么使用函数模板?

点击查看代码
template<class T>	//注意:T代表泛型的数据类型,不是只能写T,
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}
void test01()
{
	int a = 10;
	int b = 20;
	mySwap(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
}

//可以这样定义函数模板
//template<typename T>
//void func(T a, T b)
//{
//
//}

template<class T>
T func1(T a, T b)
{
	return a + b;
}
void test02()
{
	int a = 10;
	double b = 20.3;
	//如果使用参数列表指定数据类型,那么实参中可以隐式转换,
	//如果转换成功,就调用,转换不成功就报错
	cout << func1<int>(a, b) << endl;
}

普通函数和函数模板的区别

点击查看代码
//1.普通函数可以进行隐式转换,函数模版不能直接的进行隐性转换

//普通函数
int myPlus(int a, int b)
{
	cout << "普通函数" << endl;
	return a + b;
}

//函数模板
template<class T>
int myPlus(T a, T b)
{
	cout << "函数模板" << endl;
	return a + b;
}

void test01()
{
	int a = 10;
	double b = 20;
	myPlus(a, b);	//普通函数可以进行隐性转换
	//myPlus2(a, b);	//没有与参数列表匹配的 函数模板 "myPlus2" 实例	
	myPlus<int>(a, b);	//如果要进行隐性转换,必须加上参数列表
}

普通函数和函数模板的调用规则

点击查看代码
//普通函数
int myPlus(int a, int b)
{
	cout << "普通函数" << endl;
	return a + b;
}

//函数模板
template<class T>
int myPlus(T a, T b)
{
	cout << "函数模板" << endl;
	return a + b;
}
//函数模板重载
template<class T>
void myPlus(T a, T b, T c)
{
	cout << "函数模板myPlus(T a, T b, T c)" << endl;
}
//1、函数模板和普通函数都可以重载
void test02()
{
	int a = 10;
	int b = 20;
	//2、如果普通函数和函数模板都可以实现的功能,普通函数优先调用
	myPlus(a, b);
	
	//3、可以使用<>空参数列表强制调用函数模板
	myPlus<>(a, b);

	//4、函数模板之间也可以进行重载

	//5、如果函数模板可以产生更好的匹配,那么优先使用函数模板
	char c1 = 'a';
	char c2 = 'b';
	myPlus(c1, c2);
}

模板机制剖析——c++编译器是如何实现函数模板机制的?

  1. 编译器并不是把函数模板处理成能够处理任何类型的函数
  2. 函数模板通过具体类型产生不同的函数
  3. 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。

模板也具有局限性

点击查看代码
template<class T>
void mycompare(T a, T b)
{
	if (a > b)
	{
		cout << "a>b" << endl;
	}
	else
	{
		cout << "a<=b" << endl;
	}
}

void test01()
{
	//如果传入的是数组名,那么函数模板中比较函数名的大小就没有意义
	int arr[20];
	int arr2[10];

	mycompare(arr, arr2);
}

为解决上述问题,提出了两种方法

第一种:使用函数模板具体化

点击查看代码
class Maker
{
public:
	Maker(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
public:
	string name;
	int age;
};

template<class T>
void myfunc(T& a, T& b)
{
	if (a > b)
	{
		cout << "a>b" << endl;
	}
	else
	{
		cout << "a<=b" << endl;
	}
}
//具体化函数模板,注意上面的函数模板要有,才能具体化
template<>void myfunc<Maker>(Maker& a, Maker& b)
{
	cout << "函数模板的具体化" << endl;
	if (a.age > b.age)
	{
		cout << "a>b" << endl;
	}
	else
	{
		cout << "a<=b" <<
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇阅读openfoam框图 下一篇树状数组笔记整理

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目