C++模板初阶

文章目录

  • 前言
  • 一、函数模板
  • 二、类模板


前言

模板是面向对象提搞效率一种方法,模板是对于一种功能相同,只是数据类型不同的不管是函数还是类,根据一个板子,然后刻出来!如:印刷书本,或者纸张,那些纸张都是一样的,不可能手写出来对吧,根据最开始的那个书本或者纸张,印刷出大量的书本或纸张!最开始的那书本或者纸张就可以称之为模板!模板又分为函数模板和类模板。

一、函数模板

先来看交换函数,逻辑一样,只是形参类型不同,虽然它们构成函数重载,但是这些函数都需要写出来,降低了效率!

void Swap(int x, int y)
{
	int temp = x;
	x = y;
	y = temp;
}

void Swap(double x, double y)
{
	double temp = x;
	x = y;
	y = temp;
}

void Swap(char x, char y)
{
	char temp = x;
	x = y;
	y = temp;
}

交换函数它的功能都是交换两个数据,只是每次交换的这两个数据的类型可能不一样,如果像这样每次写出,很麻烦且还降低效率,可以写一个模板解决!
对于这种功能几乎一样,只是参数类型不同的,可以写成一个模板,这样的话每次使用的都是由这个函数模板生成的模具
模板关键字为template,模板参数关键字为typename/class,后面是模板参数名,具体语句template
模板参数中,参数可以不止一个,可以有很多个模板参数!

template<typename T>//模板参数可以有多个,看自己需求
void Swap(T x, T y)
{
	T temp = x;
	x = y;
	y = temp;
}

int main()
{
	int a = 1, b = 2;
	double d1 = 1.1, d2 = 2.2;
	
	Swap(a, b);
	Swap(d1, d2);

	return 0;
}

而当去调用时,并不是调用的同一个函数,而是调用由模板实例化生成具体的函数
C++模板初阶_第1张图片
这两个个调用的并不是同一个函数,而是由模板实例化生成的对应实参类型的具体类型的函数,然后再去调用实例化出的函数
像这种函数调用,函数模板根据调用,编译器会自动推导模板参数的类型,实例化出对应的函数,而这样的实例化也叫做隐式实例化
模板实例化
模板实例化:隐式实例化和显示实例化
当隐式实例化无法满足时,需要具体显示写出模板参数类型,无法完成自动推导,需要自己写出具体类型,如有些时候函数形参不是模板参数而
返回值类型是模板参数类型时,此时就需要显示实例化了,编译器无法自动推导模板参数的类型

template<class T>
T* Alloc(int n)
{
	return new T[n];
}

int main()
{
	Alloc<int>(10);
	return 0;
}

如果不显示写根本就无法推导类型!
C++模板初阶_第2张图片

显示实例化是:函数名/类名<类型>

二、类模板

以栈为例
一般的栈类

typedef int DataType;
class Stack
{
public:
	Stack(int capacity = 4)
		:_array(new DataType[capacity])
		,_capacity(capacity)
		,_top(0)
	{
		cout << "Stack(int capacity = 4)" << endl;
	}

	~Stack()
	{
		if (_array)
		{
			delete[] _array;
			_array = nullptr;
			_capacity = 0;
			_top = 0;
		}
		cout << "~Stack" << endl;
	}

private:
	int* _array;
	int _capacity;
	int _top;
};

这是一个存储int型数据的栈类,如果要存储double,float…但是它们功能的实现又是一样的,如果还是这样写效率底且麻烦,并且如果其中有bug的话,那么所有栈都要修改,这样直接哭死,写一个类模板

template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
		:_array(new T[capacity])
		, _capacity(capacity)
		, _top(0)
	{
		cout << "Stack(int capacity = 4)" << endl;
	}

	~Stack()
	{
		if (_array)
		{
			delete[] _array;
			_array = nullptr;
			_capacity = 0;
			_top = 0;
		}
		cout << "~Stack" << endl;
	}

private:
	T* _array;
	int _capacity;
	int _top;
};

int main()
{
	Stack<int> st1;
	Stack<double> st2;
	return 0;
}

这样它只是存储数据的类型不同,有什么问题直接在类模板修改即可!
但是类模板的实例化,只能显示实例化,并没有隐式实例化,因为有些数据会在类成员函数中或者其它位置,当类模板需实例化对象时需指定实例化类型!
但是类模板又不同于普通类

普通类:类名就是类型
类模板:类名是类名,类型是类名<模板参数类型>

所有类中声明和变量分离,指定类域都是要类模板显示实例化的!如:

template<class T>
class Stack
{
public:
	Stack(int capacity = 4);
		

	~Stack();
	

private:
	T* _array;
	int _capacity;
	int _top;
};

template<class T>
Stack<T>::Stack(int capacity  )
	:_array(new T[capacity])
	, _capacity(capacity)
	, _top(0)
{
	cout << "Stack(int capacity = 4)" << endl;
}


template<class T>
Stack<T>::~Stack()
{
	if (_array)
	{
		delete[] _array;
		_array = nullptr;
		_capacity = 0;
		_top = 0;
	}
	cout << "~Stack" << endl;
}

且每一个模板惨呼它的作用域是在它那个函数模板或者类模板,不会越界!
结束!

你可能感兴趣的:(c++,开发语言)