类模板
#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;
}