【C++】C++的模板初识

目录

思维导图大纲:

1. 什么是模板? 

2. 模板的分类 

区别:函数模版和模版函数 / 类模版和模版类 

2.1 函数模板 

2.1.1 用法 

 2.1.2 原理

2.1.3 函数模板的实例化 

2.1.4 模板参数的匹配原则 

2.2 类模板 

 2.2.1 用法

 2.2.2 原理

2.2.3 声明和定义分离 

2.2.4 类模板的实例化 


思维导图大纲:

1. 什么是模板? 

模板是泛型编程的一种体现,同一类代码可以多次使用!简单打个比方说,模板就相当于活字印刷术,有了这项技术我们就可以高效的拓印不同的书籍;模板也是如此:有了模版我们可以减少大量重复的代码编写,例如:我们需要写一个swap函数,需求是要交换int类型和float类型等等,如果按照原本函数重载的写法我们仍然需要写多个swap函数,有了模版我们就可以根据不同情况生成不同的swap 

2. 模板的分类 

区别:函数模版和模版函数 / 类模版和模版类 

函数模版是一个模版是一种工具,模版函数是通过模版实例化生成的一个具体的函数对象。同理类模版和模版类也是如此 

2.1 函数模板 

2.1.1 用法 

// 函数模版
template<class T>
void Swap(T& data1, T& data2)
{
	T tmp = data1;
	data1 = data2;
	data2 = tmp;
}
  • template关键字
  • <>内部是类型,关键字可以使用class/typename
  • 返回值类型 函数名(参数列表){} 

 2.1.2 原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器 

2.1.3 函数模板的实例化 

函数模板的实例化分为:

  • 隐式实例化:编译器自己去推导类型
  • 显示实例化:我们明确类型 
// 函数模版
template<class T>
void Swap(T& data1, T& data2)
{
	T tmp = data1;
	data1 = data2;
	data2 = tmp;
}

void Text01()
{
	// 函数模版的实例化
	int a = 1, b = 2;
	double c = 1.1, d = 2.2;
	// 1. 显示实例化
	Swap<int>(a, b);
	Swap<double> (c, d);
	cout << a << " " << b << endl;
	cout << c << " " << d << endl;
	// 2. 隐式实例化
	Swap(a, b);
	Swap(c, d);
	cout << a << " " << b << endl;
	cout << c << " " << d << endl;
}

2.1.4 模板参数的匹配原则 

  • 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这 个非模板函数 
  • 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而 不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
  •  模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

2.2 类模板 

 2.2.1 用法

// 类模版
template<class T>
class Stack
{
public:
	void push(const T& data)
	{
		_v.push_back(data);
	}
private:
	vector<T> _v;
};
  • template关键字
  • <>内部是类型,关键字可以使用class/typename

 2.2.2 原理

类模板的生成原理和函数模板差不多,但是是属于按需生成(实例化),类模板中的函数也属于函数模板 

2.2.3 声明和定义分离 

在不同文件中:

类模板的声明和定义不要分离到俩个文件去,会产生连接错误,造成该原因是按需实例化,C++模板的实例化是在编译时进行的,这意味着编译器在编译过程中需要看到模板的完整定义,以便为特定的类型生成实例化代码。如果模板的声明和定义被分开放置在两个文件中,编译器在编译使用模板的源文件时,可能无法找到模板的完整定义,从而导致编译失败或链接错误。 

同一个文件中:

需要声明函数的来源使用域访问符::,然后是模板参数

2.2.4 类模板的实例化 

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的 类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。 

// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值