C++练习 Day7

类模板

#include<iostream>
//注意一点,max和min使用的时候,容易引起冲突,如果写了下面一行代码,则要改变函数模板的名字,否则直接使用std::cout和std::endl;
using namespace std;
/*
不要把这里的class与类的声明关键字class混淆在一起,虽然它们由相同的字母组成,但含义是不同的。
这里的class表示T是一个类型参数,可以是任何数据类型,如int、float、char等,或者用户定义的struct、enum或class等自定义数据类型。
*/
template<class T>
T Min(T a,T b)
{
	return (a < b) ? a : b;
}
/*
为了区别类与模板参数中的类型关键字class,标准C++提出?了用typename作为模板参数的类型关键字,同时也支持使用class。
比如,把min定义的template <class T>写成下面的形式是完全等价的:
*/
template<typename T>
T myMin(T a, T b)
{
	return (a < b) ? a : b;
}
/*
模板实例化发生在调用模板函数时。当编译器遇到程序中对函数模板的调用时,
它才会根据调用语句中实参的具体类型,确定模板参数的数据类型,
并用此类型替换函数模板中的模板参数,生成能够处理该类型的函数代码,即模板函数。
当多次发生类型相同的参数调用时,只在第1次进行实例化。编译器只在第1次调用时生成模板函数,
当之后遇到相同类型的参数调用时,不再生成其他模板函数,它将调用第1次实例化生成的模板函数。
*/
int main() {
	double a = 2, b = 3.4;
	float c = 2.3, d = 3.2;
	cout << "2,3    的最小值是:" << Min<int>(2, 3) << endl;//显式调用
	cout << "2,3.4  的最小值是:" << Min(a, b) << endl;//隐式调用
	cout << "'a','b'	  的最小值是:" << Min('a', 'b') << endl;
	cout << "2.3,3.2的最小值是:" << Min(c, d) << endl;
	//cout << "2.3,3.2的最大值是:" << std::min(c, d) << endl;
	cout << "2.3,3.2的最小值是:" << myMin(c, d) << endl;//更换class为typename
	// cout<<"2,'a'    的最小值是:"<<Min(2,'a')<<endl; //报错,不同类型无法处理,请看9-3-1.cpp
	system("pause");
	return 0;
}
#include<iostream>
using namespace std;
template <class T>
T Max(T a, T b) {
	return (a > b) ? a : b;
}
/*
C++在实例化函数模板的过程中,只是简单地将模板参数替换成调用实参的类型,并以此生成模板函数,不会进行参数类型的任何转换。
*/
int main()
{
	double a = 2, b = 3.4;
	float c = 5.1, d = 3.2;
	//在模板调用时进行参数类型强制转换
	cout << "2, 3.2    的最大值是:" << Max(double(2), 3.2) << endl;
	cout << "a, c    的最大值是:" << Max(float(a), c) << endl;
	//显示指定函数模板实例化的参数类型
	cout << "'a', 3    的最大值是:" << Max<int>('a',3)<< endl;
	system("pause");
}
//模板特化
#include<iostream>
using namespace std;
template <class T>
T Max(T a, T b) {
	return (a > b) ? a : b;
}
//特化
//template <>返回类型 函数名<特化的数据类型>(参数表){}
template <>char *Max<char *>(char *a, char *b) {
	return (strcmp(a, b) >= 0) ? a : b;
}
int main()
{
	float c = 5.1, d = 3.2;
	cout << "2,3的最大值是:" << Max(2, 3) << endl;
	cout << "c,d的最大值是:" << Max(c, d) << endl;
	const char a = 'a';
	const char b = 'b';
	const char *p1 = &a;
	const char *p2 = &b;
	cout << Max(*p1, *p2) << endl;
	system("pause");
}
//函数模板参数可以是类属参数,也可以包括普通类型的参数
#include<iostream>
using namespace std;
template<class T>
//实现降序
void sort(T *a, int n) {
	for (int i = 0; i < n; i++)
	{
		int p = i;
		for (int j = i; j < n; j++)
		{
			if (a[p] < a[j])
				p = j;
		}
		T t = a[i];
		a[i] = a[p];
		a[p] = t;
	}
}
template <class T>
void display(T &a, int n) {
	for (int i = 0; i < n; i++)
		cout << a[i] << "\t";
}
int main(int argc, char const *argv[])
{
	int a[] = { 1,41,2,5,8,21,23 };
	char b[] = { 'a','x','y','e','q','g','o','u' };
	sort(a, 7);
	sort(b, 8);
	display(a, 7);
	display(b, 8);
	system("pause");
	return 0;
}

设计一个堆栈的类模板Stack,在模板中用类型参数T表示栈中存放的数据,用非类型参数MAXSIZE代表栈的大小。

/*
设计一个堆栈的类模板Stack,在模板中用类型参数T表示栈中存放的数据,用非类型参数MAXSIZE代表栈的大小。
*/
#include<iostream>
using namespace std;
template<class T,int MAXSIZE>
class Stack{
private:
	T elem[MAXSIZE];
	int top;
public:
	Stack() { top = 0; }
	void push(T e);
	T pop();
	void show();
	bool empty() {
		if (top <= -1)return 0;
		else return 1;
	}
	void setEmpty() {
		top = -1;
	}
	bool full() {
		if (top >= MAXSIZE - 1) return 1;
		else return 0;
	}
};
/*
原型:
template <模板参数列表>
返回值类型 类模板名<模板参数名表>::成员函数名 (参数列表){};
*/
template<class T,int MAXSIZE>
	void Stack<T, MAXSIZE>::push(T e) {
		if (full()){
			cout << "栈已满" << endl;
			return;
		}
			elem[++top] = e;
}
template<class T,int MAXSIZE>
T Stack<T, MAXSIZE>::pop() {
		if (empty()) {
			cout << "栈已空" << endl;
			return 0;
		}
		return elem[top--];
}
template<class T,int MAXSIZE>
void Stack<T, MAXSIZE>::show()
{
	for (int i = 0; i < top; ++i)
		cout << elem[i] << " ";
}
int main() {
	//类模板实例化
	Stack<int, 10>iStack;
	Stack<char, 10>cStack;
	iStack.setEmpty();
	cStack.setEmpty();
	cout << "-------intStack----\n";
	int i;
	for (i = 1; i < 11; i++)
		iStack.push(i);
	iStack.show();
	//for (i = 1; i < 11; i++) cout << iStack.pop() << "\t";
	//cout << "\n\n-------charStack----\n";
	//cStack.push('A');	cStack.push('B');
	//cStack.push('C'); 	cStack.push('D');
	//cStack.push('E');
	//for (i = 1; i < 6; i++)  cout << cStack.pop() << "\t";
	//cout << endl;
	system("pause");
	return 0;
}

 //设计一通用数组类,它能够直接存取数组元素,并能够对数组进行从大到小的排序。

//设计一通用数组类,它能够直接存取数组元素,并能够对数组进行从大到小的排序。
#include<iostream>
#include<string>
using namespace std;
const int Size = 5;
template<class T>
class Array {
private:
	T a[Size];
public:
	Array() {
		for (int i = 0; i < Size; i++)
			a[i] = 0;

	}
	T &operator[](int i);
	void Sort();
};
template<class T>T& Array<T>::operator[](int i) {
	if (i<0 || i>Size - 1)
	{
		cout << "\n下标越界" << endl;
		exit(1);
	}
	return a[i];
}
template<class T>void Array<T>::Sort()
{
	int p = 0;
	for (int i = 0; i < Size-1; i++)
	{
		p = i;
		for (int j = i+1; j < Size; j++)
		{
			if (a[p] < a[j])
				p = j;
		}
		T t = a[p];
		a[p] = a[i];
		a[i] = t;
	}
}
/*所谓特化,就是将泛型的东东搞得具体化一些,从字面上来解释,就是为已有的模板参数进行一
些使其特殊化的指定,使得以前不受任何约束的模板参数,或受到特定的修饰(例如const或者摇身
一变成为了指针之类的东东,甚至是经过别的模板类包装之后的模板类型)或完全被指定了下来。*/
//template <> 返回类型 类模板名<特化的数据类型>::特化成员函数名(参数表){}
//模板特化的template后的尖括号里面不需要填写
template<>void Array<char *>::Sort() {
	int p;
	for (int i = 0; i < Size - 1; i++)//这里如果使用size会遇到变量不明确的问题,主要是和using namespace std;冲突了,改个名称就好了
	{
			p = i;
	for (int j = i + 1; j < Size; j++)
	{
		if (strcmp(a[p], a[j]) < 0)
		{
			p = j;
		}
		char *t = a[p];
		a[p] = a[i];
		a[i] = t;
	}
	}
}
int main() {
	Array<int>a1;
	Array<char*>b1;
	a1[0] = 1; a1[1] = 23; a1[2] = 6;
	a1[3] = 3; a1[4] = 9;
	a1.Sort();
	for (int i = 0; i < 5; i++)
		cout << a1[i] << "\t";
	cout << endl;
	char c = 'c';	char g = 'g';	char u = 'u';
	char i = 'i';	char p = 'p';
	b1[0] = &c;	b1[1] = &g;	b1[2] = &u;
	b1[3] = &i;	b1[4] = &p;
	b1.Sort();
	for (int i = 0; i < 5; i++)
		cout << *b1[i] << "\t";
	cout << endl;
	system("pause");
	return 0;
}

 遇到的错误1:size的“变量不明确”,主要是因为size和using namespace std;的名称冲突了,改个名称就好了

遇到的错误2:“形参表不匹配”,主要是形参写错了,仔细看看就好

STL:map

#include<iostream>
#include<string>
#include<map>
using namespace std;

int main(int argc, char const *argv[])
{
	string name[] = { "张三","李四","王麻子" };
	double salary[] = { 1200,2000,1450 };
	map<string, double>sal;
	for (int i = 0; i < 3; i++)
	{
		sal.insert(make_pair(name[i], salary[i]));
	}
	sal["wanwu"] = 1000;
	sal["bitch"] = 3939;
	for (auto p = sal.begin(); p != sal.end(); ++p)
	{
		cout << p->first << "\t" << p->second << endl;
	}
	string person;
	cout << "请输入需要查找的人" << endl;
	cin >> person;
	int flag = 1;
	for (auto p = sal.begin(); p != sal.end(); ++p)
	{
		if (p->first == person)
		{
			cout << p->second << endl;
			flag = 0;
		}
	}
	if (flag)
		cout << "没找到" << endl;
	cout << "输入待删除的人员的姓名:";
	cin >> person;
	auto it = sal.find(person);
	if (it != sal.end())
	{
		cout << "查找成功:" << (*it).first << ":" << (*it).second << endl;
		sal.erase(it);
		cout << "删除成功" << endl;

	}
	cout << "删除后的结果为" << endl;
	for (auto p = sal.begin(); p != sal.end(); p++) {
		cout << p->first << p->second << endl;
	}

	system("pause");
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

师父祭天法力无边

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值