C++ 模板与STL

544 阅读4分钟

引进模板意义:在编程时,我们有时会遇到这样的情况:多个函数的功能相同或相似,只是数据类型不同。

如: 1)

int  min(int a, int b)
{
	if (a<b)
		return a;
	else
		return b;
}

2)

double min(double a, double b)
{
	if (a<b)
		return a;
	else
		return b;
}

3)

char min(char a, char b)
{
	if (a<b)
		return a;
	else
		return b;
}

这三个函数业务逻辑一样,数据类型不一样。我们能否用如下通用函数表示呢?

T min(T a, T b)
{
	if (a<b)
		return a;
	else
		return b;
}

可以,这就是函数模板。对于类的声明来说,也有同样的问题。有时,有两个类或多个类,其功能相同,只是数据类型不同,这可以定义类模板。

void myswap(int& a,int& b){
	int tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
}

void myswap(char& a, char& b){
	char tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
}

以上两个方法同样可以定义成模板

template <typename T>
void myswap(T& a, T& b){
	T tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
}

运行

void main(){
	//根据实际类型,自动推导
	int a = 10, b = 20;
	myswap<int>(a, b);
	cout << a << "," << b << endl;

	char x = 'v', y = 'w';
	myswap(x, y);
	cout << x << "," << y << endl;

	system("pause");
}

C++.png

模板的概念 模板(template)是C++的一个新的重要特性,它对具有相同功能的函数或类的再抽象,把数据类型参数化,用一种或多种抽象的类型来表示(称为类属类型),再用一个通用形式来表示多个功能相似而数据类型不同的函数或类,实现代码重用的目的。 实际使用时,再用具体的类型去替代模板中的类属类型,这称为实例化。

模板的种类:有两种 函数模板:实例化的函数模板称为模板函数; 类模板:实例化的类模板称为模板类

C++.png

模板函数

函数模板只是模板的定义,定义中用到通用类型参数,不能直接执行; 模板函数是当编译系统发现有一个函数调用:函数名(实参表) 时,根据实参表中的类型生成一个重载函数,它是一个实实在在的函数定义,具有程序代码; 模板函数的各参数之间必须保持完全一致的类型,不具有隐式的类型转换;

template <typename T>
void myswap(T& a, T& b){
	T tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
}

函数模板的优点: 1)克服了C语言用大量不同函数名表示相似功能的坏习惯;

2)克服了宏定义不能进行参数类型检查的弊端;

3)克服了C++函数重载用相同函数名字重写几个函数的烦琐;

4)奠定了标准模板库STL的基础(该库包含了许多在计算机科学领域里常用的基本数据结构和基本算法。为广大软件设计人员提供了一个可扩展的应用框架,体现了软件的高度可复用性。)

类模板

类模板的定义

template < 类型形参表 >
class 类模板名
{
private:
	私有成员定义
public:
	公有成员定义
protected:
	受保护成员定义
};

说明: 类模板的成员函数可以在模板内定义,也可以在模板外定义; 类模板成员函数的模板外定义格式如下: template < 类型形参表 > 返回类型 类模板名 <类型形参表>::函数名(形参表) { ...... }

说明:

1)类模板只是模板的定义,定义中用到通用类型参数,不能直接执行;

2)模板类是实实在在的类定义,是类模板的实例。可以将 类模板名 <模板实参表> 看作是一个类;

3)利用模板类还可以定义对象,格式如下:

类模板名 <模板实参表> 对象名

类模板名 <模板实参表> 对象名([构造函数实参表])

template<class T>
class A{
public:
	A(T a){
		this->a = a;
	}
protected:
	T a;
};

//普通类继承模板类
class B : public A<int>{
public:
	B(int a, int b) : A<int>(a){
		this->b = b;
	}
private:
	int b;
};

//模板类继承模板类
template <class T>
class C : public A<T>{
public:
	C(T c, T a) : A<T>(a){
		this->c = c;
	}
protected:
	T c;
};

void main(){
	//实例化模板类对象
	//List<String> list;
	A<int> a(6);
	system("pause");
}

标准模板库

标准模板库(Standard Template Library)是ANSI / ISO C++最有特色、最实用的部分之一 STL包含了以下三部分的内容:

容器类(container):是容纳一组对象或对象集的类

迭代器(iterator):面向对象版本的指针,它提供了访问容器或序列中每个对象的方法

算法(algorithm):用来操作容器中的元素的函数模板

泛型算法(generic algorithm)和函数对象(function object)的概念与使用使算法摆脱了对不同类型数据个性操作的依赖,这样就可以编出更具通用性的算法。

具体的STL可以到网上查看其包含内容的函数。