C++——模板

        C 语言中,若要对不同类型实现相同操作,只能为每种类型单独定义函数。例如Swap函数,实现有些小小的麻烦。

void SwapInt(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

void SwapDouble(double* x, double* y)
{
	double tmp = *x;
	*x = *y;
	*y = tmp;
}

int main()
{
	int a = 1, b = 2;
	double c = 3.3, d = 4.4;
	SwapInt(&a, &b);
	SwapDouble(&c, &d);
	return 0;
}

        C++提出模板,提高了代码的复用性,能够处理多种不同的数据类型。

        模板主要包含两部分:函数模板和类模板。

        一、函数模板

        基本语法:template。template是声明模板的关键字,其中typename也可以用class替代,T是模板参数,表示“任意类型”。

        函数模板本身不是可执行的函数,而是生成具体函数的蓝图,编译器会根据调用时的实参类型生成对应的函数实例。调用时,编译器根据所传参数和函数模板自动产生函数供我们使用,这个过程叫函数模板的实例化。

        如下,Swap(a, b)和Swap(c, d)其实调用的不是同一个函数,而是编译器生成的两个参数类型分别为int和double的函数。

template
void Swap(T& x, T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 1, b = 2;
	double c = 3.3, d = 4.4;
	Swap(a, b);
	Swap(c, d);
	return 0;
}

        还可以支持多个类型参数。

template
T1 Add(const T1& x, const T2& y)
{
	return x + y;
}

        函数模板的实例化分为隐式实例化和显式实例化。上面的两个例子都是隐式实例化,由编译器根据传递的实参推导T是什么类型。

        有些时候编译器不能推导出T的类型,就要显式实例化。显式实例化在调用函数时要指定类型,在函数名后面加<>,<>里面写类型。

        以下例子编译器无法通过实参推断T是什么类型,所以要显式实例化。

template
T* Array(int n)
{
	T* arr = new T[n];
	return arr;
}

int main()
{
    Array(10);
	return 0;
}

        二、类模板

        类模板定义“通用类”,其中成员函数和成员变量都依赖模板参数。使用时必须显式指定类型,不能像函数模板那样隐式推导类型。

template
class Stack
{
public:
	Stack(int InitSize = 4)
	{
		_a = new T[InitSize];
		_size = 0;
		_capacity = InitSize;
	}

	~Stack()
	{
		if (_a != nullptr)
		{
			delete[] _a;
			_size = _capacity = 0;
		}
	}
private:
	T* _a;
	int _size;
	int _capacity;
};

int main()
{
	Stack st1(5);
	Stack st2(10);

	return 0;
}

        类模板是创建模板类的“蓝图”,模板类是类模板实例化后的具体类,这时两个不同的概念。

       如果类模板的成员函数声明与定义分离,则每个成员函数前都必须添加模板声明,且函数名前需通过“类名::”指明类域。

        以上面的Stack为例:普通类中,类名与类型完全一致(均为Stack);但类模板中,Stack是类名,Stack、Stack才是具体的类型(称为‘模板类’)。

template
class Stack
{
public:
	Stack(int InitSize = 4);

	~Stack();
private:
	T* _a;
	int _size;
	int _capacity;
};

template
Stack::Stack(int InitSize)
{
	_a = new T[InitSize];
	_size = 0;
	_capacity = InitSize;
}

template
Stack::~Stack()
{
	if (_a != nullptr)
	{
		delete[] _a;
		_size = _capacity = 0;
	}
}

你可能感兴趣的:(c++,算法,数据结构)