C++模板

交换两个数很简单,可以直接在函数里面交换,但如果不只是int类型,假如要交换的是double类型甚至是自定义类型呢?

也简单,直接把写好了的复制粘贴,在把类型改一改。

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;
}

可以发现,我们要实现的函数极为相似,除了类型不同其他地方完全一样。那既然都差不多,有没有一种方式让编译器根据不同的类型来生成我们需要的函数呢?     

为了提高效率,C++引进了函数模板来解决此类问题。

函数模板格式
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名 ( 参数列表 ){}
template <typename T>
void Swap(T &x, T &y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

这时候编译器就会根据传递的类型,来生成不同的函数。

比如这里想交换int就传int,想交换double型就传double型,想交换自定义类型就传自定义类型。

能够这样做的原因是,此时编译器也完成了一件事:函数模板的实例化。

void Test3()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	Swap(a, b);
	Swap(c, d);
}

当交换int型时,它会实例化成int类型的交换函数,也就是和上面的SwapINT函数没有任何区别,当交换bouble型时,它会实例化为double类型的交换函数,也就是上面的SwapDOUBLE函数

值得注意的是,    Swap(a, b);和  Swap(c, d);他们不是同一个函数,这一点可以通过反汇编的角度证明:

如果是同一个函数,他们call的地址应当是相同的,但这里 Swap(a, b)它call的是Swap<int>的地址,Swap(c,d)它call的是Swap<double>的地址。很明显,他们调用的不是同一个函数。

那这里int型的a和double型的c能不能完成交换?

这些都是靠编译器自动去匹配识别类型,所以这种不明显的函数模板实例化叫做隐式实例化。所以a和c是无法完成交换的,因为他们的类型都无法匹配。

反之,显式实例化就是显式去传类型。

举个例子:

template<typename Type>
Type* func(int n=1)
{
	Type *p = new Type[n];
	return p;
}

void Test3()
{
	func<int>(4);
}

func函数无法很好的匹配类型,所以func函数想要实例化只能通过显示实例化。

总结一下类型参数的匹配原则:
1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函
2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模 板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

不仅仅是函数,类同样也可以使用模板。

下面用栈来做示范。

平时的栈都只能存一种数据类型,而C++的类模板可以实例化出各种不同类型的栈。

template <typename S>
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = new S[capacity];
		_capacity = capacity;
		_size = 0;
	}
	~Stack()
	{
		delete[] _a;
		_a = nullptr;
		_capacity = _size = 0;
	}
private:
	S *_a;
	int _size;
	int _capacity;
};

这样,对于各种类型的栈,都能够很好的被实例化出来。

不过类模板和函数模板在一些细节上还是有些差异:

在类和对象中,类名代表类型,类模板的实例化需要在类模板的名字后面加<>,在将实例化的类型放入<>里面,类模板的名字不是真正的类,真正的类是那个实例化的结果。

//Stack是类名,Stack<int>和Stack<double>才是类型
Stack<int> st1;
Stack<double> st2;

一个类里构造/析构函数的格式是类名+(),这也就不难解释为什么栈里面的构造/析构函数直接就是Stack(),而非Stack<>()。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值