函数模板+类模板

本文详细介绍了C++中的函数模板和类模板的使用,包括模板实例化、类型推演以及显示实例化的过程。通过Swap和Add函数模板的实例,展示了模板在不同情况下的应用,如隐式类型转换和强制类型转换。同时,讨论了模板匹配原则,以及在有现成函数与模板函数共存时的选择。最后,对比了C语言与C++中类模板的区别,强调C++类模板的便利性和显示实例化的必要性。
摘要由CSDN通过智能技术生成

函数模板

Swap模板

函数模板实例化过程

  • 模板的推演,推演T的具体类型是什么
  • 再实例化生成具体的函数 在这里插入图片描述
    库里有Swap函数以后直接用
//template<class T>
//template<class T1, class T2, class T3>
//template<typename T>
template<class T>
void Swap(T& x1, T& x2)
{
	//T tmp = x1;
	T tmp(x1);//拷贝构造
	x1 = x2;
	x2 = tmp;
}
int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	Swap(a, b);
	Swap(c, d);

	char c1 = 'A', c2 = 'a';
	Swap(c1, c2);

	int* p1 = &a, *p2 = &b;
	Swap(p1, p2);
	return 0;
}

Add模板

  • 通过转换匹配类型来运行
int Add(const int& left, const int& right)
{
	return left + right;
}
int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;
	//隐式类型转换
	cout << Add(a1, d2) << endl;
}
  • 模板需要强转类型或者显示实例化指定T的类型才能运行
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;
	// 实参去推演形参的类型
	cout << Add(a1, a2) << endl;
	cout << Add(d1, d2) << endl;
	cout << Add(a1, (int)d2) << endl;
	cout << Add((double)a1, d2) << endl;

	// 不需要推演,显示实例化指定T的类型
	cout << Add<int>(a1, d2) << endl;
	cout << Add<double>(a1, d2) << endl;
}

  • 显示实例化
template<class T>
T func(int x)
{
	T a(x);
	return a;
}
int main()
{
	// func(1);--err
	// 有些函数模板里面参数中没用模板参数,函数体内才有用
  // 无法通过参数推演T的类型,只能显示实例化
	func<A>(1);
	func<int>(1);
}

模板匹配原则:

  • 有现成完全匹配的,那就直接调用,没有现成调用的,实例化模板生成
  • 有需要转换匹配,那么它会优先选择去实例化模板生成
  • 完全普配 > 模板 > 转换匹配 – 调用
//专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
	return left + right;
}
int main()
{
	//有现成完全匹配的那就直接调用,没有现成调用的,实例化模板生成
	//若没有模板则调用专门处理int的函数进行转换匹配
	Add(1, 2);
	Add<int>(1, 2);
	
	// 有需要转换匹配--优先选择实例化模板生成,没有模板才会使用int的(隐式类型转换)
	Add(1.1, 2.2);
	return 0;
}

类模板

c语言

typedef int STDataType;
class Stackint
{
private:
	STDataType* _a;
	int _top;
	int _capacity;
};
class Stackdouble
{
private:
	STDataType* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack st1; // int
  Stack st2; // double
	return 0;
}

C++使用类模板更加方便

  • 类模板的使用不通过推演,都是使用显示实例化指定的类型
  • 模板不支持声明写到.h,定义写到cpp,会报理解错误
struct TreeNode
{
	// ...
};
template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
		:_a(new T[capacity])
		, _top(0)
		, _capacity(capacity)
	{}
	~Stack()
	{
		delete[] _a;
		_a = nullptr;
		_top = _capacity = 0;
	}
	// 类里面声明,类外面定义
	void Push(const T& x);//只插入数据不改变x用const
private:
	T* _a;
	int _top;
	int _capacity;
};
// 普通类,类名就是类型
// 类模板,类名不是类型,类型是Stack<T>
template<class T>
void Stack<T>::Push(const T& x)
{
	// ...
}
int main()
{
	// 类模板的使用都是显示实例化--因为没有办法指定T
	Stack<TreeNode*> st1; // TreeNode*
	Stack<int> st2; // int
	st2.Push(1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值