C++ 模板

目录

1.泛型编程

2.函数模板

3.类模板


1.泛型编程

如果在C++中,能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件 (即生成具体类型的代码),那将会节省许多头发。巧的是前人早已将树栽好,我们只需在此乘凉。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
关于泛型的理解可以总结下面的一句话,它是把数据类型作为一种参数传递进来。
模板是泛型编程的基础,可分为 函数模板和类模板两大类。

2.函数模板

c语言实现交换函数

void swapi(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
 
void swapd(double* x, double* y)
{
	double tmp = *x;
	*x = *y;
	*y = tmp;
}
 
void swapc(char* x, char* y)
{
	char tmp = *x;
	*x = *y;
	*y = tmp;
}
int main()
{
	int a = 10, b = 20;
	double c = 0.1,d = 0.5;
	char e = 'a', f = 'b';
	swapi(&a, &b);
	swapd(&c, &d);
	swapc(&e, &f);
	return 0;
}

太繁琐了,我们C++可以用模板

template <typename T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
int main()
{
	int a = 10, b = 20;
	double c = 0.1, d = 0.5;
	char e = 'a', f = 'b';
	Swap(a, b);
	Swap(c, d);
	Swap(e, f);
	return 0;
}

函数模板格式: template <class / typename  T>

这里关键字typename和class效果一样,后面名字用T或者Tp等等都可以。

我们再看下面一个例子

template <typename T>
T Add(const T& x, const T& y)
{
	return x + y;
}
int main()
{
	int a1 = 10, a2 = 20;
	double b1 = 0.1, b2 = 0.5;
 
	cout << Add(a1, a2) << endl;
	cout << Add(b1, b2) << endl;
 
	//error
	cout << Add(a1, b2) << endl;
	cout << Add(b1, a2) << endl;
	
	return 0;
}

 下面为什么会出错呢,因为类型不同,编译器也不知道要那个类型

解决办法

1.用户自己强制类型转换

 
	//强制类型转化
	cout << Add(a1, (int)b2) << endl;
	cout << Add(b1, (double)a2) << endl;

2、显示实例化

 
	//显示实例化
	cout << Add<int>(a1, b2) << endl;
	cout << Add<double>(b1, a2) << endl;

3、通用加法函数模板

template <typename T1,typename T2>
T1 Add(const T1& x, const T2& y)
{
	return x + y;
}
int main()
{
	int a1 = 10, a2 = 20;
	double b1 = 0.1, b2 = 0.5;
	cout << Add(a1, b2) << endl;
	cout << Add(b1, a2) << endl;
	return 0;
}

 

T1为模板,以a1,b1为模板,打印出来,a1为int,b1为double。

这个是T2为模板,b2,a2,打印出来 

如果已经存在一个Add函数,那么编译器会调用该函数还是模板?

会直接调用函数,因为调用模板,模板还是会调用函数,多此一举。

3.类模板

C++中类模板的声明格式为template<模板形参表声明><类声明>,

并且类模板的成员函数都是模板函数

template  <class T1, class T2, ..., class Tn>
 
class 类模板名
 
{ 
    // 类内成员定义
};

以动态顺序表为例:

// 动态顺序表
 
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Vector
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}
 
	// 使用析构函数演示:在类中声明,在类外定义。
	~Vector();
 
	void PushBack(const T& data);
	void PopBack();
		// ...
	size_t Size() { return _size; }
 
	T& operator[](size_t pos)
	{
	assert(pos < _size);
	return _pData[pos];
	}
private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};
 
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
	if (_pData)
		delete[] _pData;
	_size = _capacity = 0;
}
int main()
{
	// Vector类名,Vector<int>才是类型
	Vector<int> s1;
	Vector<double> s2;
	return 0;
}

Vector是类名,Vector<int>才是类型。

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

还要注意:类模板中函数放在类外进行定义时,需要加模板参数列表

template <class T>
Vector<T>:: 函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值