//第八章 泛型编程技术
//泛型编程技术代表高效、可重复利用。
//要实现一种语言机制,可以交互的使用组件,比如容器及算法。
//本章从STL中涉及的容器、迭代器及算法思想讲述泛型编程技术
//129 绕过形参限制(最简单的模板例程)
//模板可以不理会形参的类型,不同的数据类型都可以调用该函数。
//定义函数模板的一般形式如下:
//template <class T> 返回类型 函数名(参数列表)
#include <iostream>
using namespace std;
template<class T> void output(T a)
{
cout<<a<<endl;
}
void main()
{
output(1);
output(3.4);
}
//130 万能计算器 (支持各类数据的加法函数)
//实现万能加法计算器,函数模板可以适用于不同类型的数据进行加法运算,不用重载函数。
#include <iostream>
using namespace std;
template<class T> T add(T a,T b)
{
return a+b;
}
void main()
{
cout<<add(1.2,3.4)<<endl;
cout<<add(1,2)<<endl;
}
//131 输出浮点型数据和整形数据(隐式和显式实例化)
//函数模板实现定义一系列功能相同的函数,即重载。
//为了对输入的特定参类型进行操作,首先要对函数模板进行实例化
//一般情况下,函数的模板的实例化都是隐式的。
//但当程序不能根据被传入的实参类型对模板函数进行实例化时,需要显式实例化
//模板函数。
#include <iostream>
using namespace std;
template<class T> void output(T a)
{
cout<<a<<endl;
}
void main()
{
cout<<"隐式实例化输出"<<endl;
output(1);
output(2.2);
cout<<"显式实例化输出"<<endl;
output<int>(34);
output<double>(3.14);
}
//132 使用模板特化判断结构体的最大值
#include<iostream>
using namespace std;
struct data
{
int a;
char ch;
};
template<class T> T mymax (const T t1,const T t2)
{
return t1<t2?t2:t1;//返回最大值
}
const struct data mymax(const struct data t1,const struct data t2)
{
if (t1.a>t2.a)
{
return t1;
}
else if(t1.a==t2.a)
{
if(t1.ch>=t2.ch)
{
return t1;
}
else
{
return t2;
}
}
else
{
return t2;
}
}
void main()
{
data a,b;
a.a=4;
a.ch='c';
b.a=1;
b.ch='t';
cout<<mymax(2,15)<<" ";
cout<<mymax('b','x')<<" ";
cout<<mymax(true,false)<<" ";
cout<<"<"<<mymax(a,b).a<<","<<mymax(a,b).ch<<">"<<endl;
}
//133模板函数的重载例程
#include<iostream>
using namespace std;
template<class T> T add(T a,T b)
{
return a+b;
}
template<class T> T add(T a,T b,T c)
{
return a+b+c;
}
void main()
{
cout<<add(1,2)<<endl;
cout<<add(1.2,3.4,4.5)<<endl;
}
//134 补充代码是输出结果成立
#include<iostream>
using namespace std;
struct var
{
int var_int1;
int var_int2;
double var_dou1;
double var_dou2;
double var_dou3;
};
template<class T> T add(T a,T b)
{
return a+b;
}
template<class T> T add(T a,T b,T c)
{
return a+b+c;
}
void main()
{
var _var;
_var.var_int1=3;
_var.var_int2=2;
_var.var_dou1=3.14;
_var.var_dou2=3.145666;
_var.var_dou3=0.145666;
cout<<"结构体var中的两个整形变量的加法结果是:"<<add(_var.var_int1,_var.var_int2)<<endl;
cout<<"结构体中的三个double型变量的加法结果:"<<add(_var.var_dou1,_var.var_dou2,_var.var_dou3);
}
//135 NXN的值
#include<iostream>
using namespace std;
template<class T> T chengfa(T a,T b)
{
return a*b;
}
void main()
{
int a=1;
int b=6;
cout<<chengfa(a,b)<<endl;
}
//136判断参数为字符串类型就输出字符串
#include<iostream>
#include<string>
using namespace std;
template <class T> void output(T a)
{
cout<<"参数类型是:"<<typeid(a).name()<<endl;
if(strstr(typeid(a).name(),"char")!=NULL)
{
//strstr 是C风格字符串的函数strstr
if(strlen(typeid(a).name())==4)
{}
else
{
cout<<"字符串"<<endl;
}
}
}
void main()
{
string str="13";
output(str);
int var1=1;
output(var1);
double var2=2.245;
output(var2);
char ch[]="1234";
output(ch);
output('d');
output("689");
}
//137 求AB对象的和(类参数)
#include<iostream>
using namespace std;
class A
{
private:
int a;
public:
A(int x){a=x;}
int getVar() const{return a;}
};
class B
{
private:
int a;
public:
B(int x){a=x;}
int getVar() const{return a;};
};
template<class T1,class T2> void add(T1 t1,T2 t2)
{
cout<<"AB对象的和:"<<t1+t2<<endl;
}
void main()
{
A _a(5);
B _b(4);
add(_a.getVar(),_b.getVar());
}
//138 输出内存区域的各类型数据(void *)
//void*也使泛型编程的一种,它可以接收任意类型的指针
#include <iostream>
#include<string>
using namespace std;
void output (void* p,char ch)
{
switch(ch)
{
case 'a':
{
int *ap=(int * )p;
cout<<*ap<<endl;
}
break;
case 'b':
{
char* chp=(char*)p;
cout<<*chp<<" "<<endl;
}
break;
case 'c':
{
double* dp=(double*)p;
cout<<*dp<<" "<<endl;
}
break;
case 'd':
{
string* strp=(string*)p;
cout<<*strp<<" "<<endl;
}
break;
}
}
void main()
{
int a=4;
char ch='a';
double d=0.2222;
string str="hello";
output(&a,'a');
output(&ch,'b');
output(&d,'c');
output(&str,'d');
cout<<endl;
}
//139 变幻的对象---使用template定义一个模板
#include<iostream>
using namespace std;
template<class T> class output
{
private:
T var1;
public:
output(const T& v):var1(v){}
T var()
{return var1;};
};
void main()
{
output<double> x(1.0);
output<int> j(3);
output<char*> str("5.0");
cout<<x.var()<<endl;
cout<<j.var()<<endl;
cout<<str.var()<<endl;
}
//140分离类模板的声明和定义(求最大值)
#include<iostream>
using namespace std;
template <class T> class MAX
{
private:
T x,y;
public:
MAX(T v1,T v2);
T getmax(MAX &a);
};
template <class T>
MAX<T>::MAX(T v1,T v2)
{
x=v1;
y=v2;
}
template <class T>
T MAX<T>::getmax(MAX &a)
{
return a.x>a.y?a.x:a.y;
}
void main()
{
MAX<int> x(1,2);
cout<<"最大值:"<<x.getmax(x)<<"\n";
}
//141 类模板含有多个类型参数
#include<iostream>
using namespace std;
template<class T1,class T2>
class multitype
{
private:
T1 x;
T2 y;
public:
multitype(T1 t1,T2 t2);//构造函数
void show();
};
template <class T1,class T2>
multitype<T1,T2>::multitype(T1 t1,T2 t2)
{
x=t1;
y=t2;
}
template<class T1,class T2>
void multitype<T1,T2>::show()
{
cout<<x<<" "<<y<<endl;
}
void main()
{
multitype<int,double> m(1,2.1);
m.show();
}
/
/142 类模板的静态成员变量
Main.cpp
#include "1.h"
void show1();
void show2();
void main()
{
show1();
show2();
}
1.h
#include<iostream>
using namespace std;
template<class T>
class A
{
private:
int x;
public:
static int a;
A(int xx);
};
1.cpp
#include"1.h"
template<class T>int A<T>::a=0;
template <class T>
A<T>::A(int xx)
{
x=xx;
a++;
}
void show1()
{
A<int> c(23);
cout<<"1.cpp---static ="<<c.a<<endl;
}
2.cpp
#include"1.h"
void show2()
{
A<int> c(33);
cout<<"2.cpp中的static a="<<c.a<<endl;
}
//145 类模板的继承
#include <iostream>
using namespace std;
template<class T1,class T2>
class A
{
private :
T1 X;
T2 Y;
public:
A(){}
A(T1 X,T2 Y);
void show();
~A(){}
};
template <class T1,class T2>
A<T1,T2>::A(T1 x,T2 y)
{
X=x;
Y=y;
}
template<class T1,class T2>
void A<T1,T2>::show()
{
cout<<"X="<<X<<endl<<"Y="<<Y<<endl;
}
template<class T1,class T2>
class B:public A<T1,T2>
{
public:
B(){}
B(T1 x,T2 y,T1 w,T2 l);
void display();
~B(){}
private:
T1 W;
T2 H;
};
template<class T1,class T2>
B<T1,T2>::B(T1 x,T2 y,T1 w,T2 h):A(x,y)
{
W=w;
H=h;
}
template<class T1,class T2>
void B<T1,T2>::display()
{
cout<<"W="<<W<<endl<<"H="<<H<<endl;
}
void main()
{
B<int,double> *q=new B<int,double>(2,3.3,1,2.1);
cout<<"派生类成员变量:"<<endl;
q->display();
cout<<"基类成员变量:"<<endl;
q->show();
delete q;
}
//146 使用STL库创建容器
//容器分为三类:
//(1)顺序性容器:vector、deque、list
//(2)关联式容器:set、multiset、map、multimap
//(3)容器适配器:stack、queue、priority_quue
#include<iostream>
#include<vector>
#include<deque>
#include<list>
#include<set>
#include<map>
#include<string>
using namespace std;
void main()
{
vector<int> v(4.1);
deque<float> deq;
deq.push_back(1);
deq.push_back(2);
deq.pop_back();
deq.push_front(3);
list<int> l;
l.push_back(1);
set<short> _set;
_set.insert(1);
_set.insert(2);
_set.insert(3);
multiset<short> _mset;
_mset.insert(4);
_mset.insert(5);
_mset.insert(6);
map<string,string> _map;
_map.insert(pair<string,string>("1","1"));
_map.insert(pair<string,string>("1","2"));
multimap<string,string> _mmap;
_mmap.insert(pair<string,string>("1","1"));
_mmap.insert(pair<string,string>("1","2"));
cout<<"vector的大小:"<<v.size()<<endl;
cout<<"deque的大小:"<<deq.size()<<endl;
cout<<"list的大小:"<<l.size()<<endl;
cout<<"set的大小:"<<_set.size()<<endl;
cout<<"multiset的大小:"<<_mset.size()<<endl;
cout<<"map的大小:"<<_map.size()<<endl;
cout<<"multimap的大小:"<<_mmap.size()<<endl;
}
//147 打印容器元素
#include<iostream>
#include<vector>
#include<deque>
#include<list>
#include<set>
#include<map>
#include<string>
using namespace std;
void main()
{
vector<int> v(4.1);
deque<float> deq;
deq.push_back(1);
deq.push_back(2);
deq.pop_back();
deq.push_front(3);
list<int> l;
l.push_back(1);
set<short> _set;
_set.insert(1);
_set.insert(2);
_set.insert(3);
multiset<short> _mset;
_mset.insert(4);
_mset.insert(5);
_mset.insert(6);
map<string,string> _map;
_map.insert(pair<string,string>("1","1"));
_map.insert(pair<string,string>("1","2"));
multimap<string,string> _mmap;
_mmap.insert(pair<string,string>("1","1"));
_mmap.insert(pair<string,string>("1","2"));
cout<<"vector的大小:"<<v.size()<<endl;
cout<<"deque的大小:"<<deq.size()<<endl;
cout<<"list的大小:"<<l.size()<<endl;
cout<<"set的大小:"<<_set.size()<<endl;
cout<<"multiset的大小:"<<_mset.size()<<endl;
cout<<"map的大小:"<<_map.size()<<endl;
cout<<"multimap的大小:"<<_mmap.size()<<endl;
list<int>::iterator lit;
set<short>::iterator iset;
multiset<short>::iterator mul;
map<string,string>::iterator mit;
multimap<string,string>::iterator mmit;
cout<<"vector中的元素:";
for (int i=0;i<v.size();i++)
{
cout<<v.at(i)<<" ";
}
cout<<endl;
cout<<"deque中的元素:";
for (int i=0;i<deq.size();i++)
{
cout<<deq.at(i)<<" ";
}
cout<<endl;
cout<<"list中的元素:";
for (lit=l.begin();lit!=l.end();lit++)
{
cout<<*lit<<" ";
}
cout<<endl;
cout<<"set中的元素:";
for (iset=_set.begin();iset!=_set.end();iset++)
{
cout<<*iset<<" ";
}
cout<<endl;
cout<<"multiset中的元素值:";
for (mul=_mset.begin();mul!=_mset.end();mul++)
{
cout<<*mul<<" ";
}
cout<<endl;
cout<<"map:";
for(mit=_map.begin();mit!=_map.end();mit++)
{
cout<<mit->first<<" "<<mit->second<<" ";
}
cout<<endl;
cout<<"multimap:";
for(mmit=_mmap.begin();mmit!=_mmap.end();mmit++)
{
cout<<mmit->first<<" "<<mmit->second<<" ";
}
cout<<endl;
}
//148 队列镜像
#include<iostream>
#include<queue>
#include<list>
using namespace std;
void main()
{
queue<int> qu;
queue<int> qu_copy;
list<int> l;
list<int>::iterator lit;//链表迭代器
qu.push(1);
qu.push(2);
qu.push(3);
qu.push(4);
cout<<"原队列元素:";
while(qu.empty()!=true)
{
l.push_front(qu.front());//首元素读出
cout<<qu.front()<<" ";
qu.pop();
}
cout<<endl;
for(lit=l.begin();lit!=l.end();lit++)
{
qu_copy.push(*lit);
}
cout<<"镜像队列:";
while(qu_copy.empty()!=true)
{
cout<<qu_copy.front()<<" ";
qu_copy.pop();
}
cout<<endl;
}
//149 获取队列头尾
#include<iostream>
#include<queue>
using namespace std;
void main()
{
queue<int> qu;
qu.push(1);
qu.push(2);
qu.push(3);
qu.push(4);
cout<<"队列头元素:"<<qu.front()<<endl;
cout<<"队列尾元素:"<<qu.back()<<endl;
}
//150 插队(在容器内插入元素)
#include<iostream>
#include<queue>
#include<list>
using namespace std;
void main()
{
int i=5;
int count=2;
queue<int> qu;
list<int> l;
list<int>::iterator lit;
qu.push(1);
qu.push(2);
qu.push(3);
qu.push(4);
cout<<"原队列元素:";
while(qu.empty()!=true)
{
l.push_back(qu.front());
cout<<qu.front()<<" ";
qu.pop();
}
cout<<endl;
cout<<"接下来在第二个元素后插入元素5,6,7"<<endl;
cout<<"最终的队列元素是:";
lit=l.begin();
while(count>0)
{
cout<<*lit<<" ";
qu.push(*lit);
lit++;
count--;
}
while(i<8)
{
cout<<i<<" ";
qu.push(i);
i++;
}
for(;lit!=l.end();lit++)
{
cout<<*lit<<" ";
qu.push(*lit);
}
cout<<endl;
}
//151 裁员计划--获取容器元素的个数、删除和清空容器元素
#include<iostream>
#include<list>
using namespace std;
void main()
{
list<int> l;
list<int>::iterator lit;
int num=0;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
num=l.size();
cout<<"容器1的个数:"<<num<<endl;
for(lit=l.begin();lit!=l.end();lit++)
{
cout<<*lit<<endl;
}
cout<<endl;
l.erase(l.begin());//删除首元素
l.pop_back();//删除最后一个元素
l.pop_front();//删除首元素
l.remove(3);//删除值为3的元素
for(lit=l.begin();lit!=l.end();lit++)
{
cout<<*lit<<" ";
}
cout<<endl;
l.clear();
}
//152 图书印刷 ---幅值元素并自动输出
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void main()
{
char ch[12]="Hello World";
vector<char> v_src(12,' '),v_dist(12,' ');//源向量和目标向量
cout<<"图书样本内容:";
for(int i=0;i<12;i++)
{
v_src.at(i)=ch[i];
cout<<ch[i];
}
cout<<endl;
copy(v_src.begin(),v_src.end(),v_dist.begin());//把v_src复制到v_dist
cout<<"经过印刷,图书内容为:";
for(int i=0;i<12;i++)
{
cout<<v_dist.at(i)<<" ";
}
cout<<endl;
}
//153 利用容器适配器实现栈功能
#include<iostream>
#include<stack>
using namespace std;
void main()
{
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
while(!st.empty())
{
cout<<st.top()<<" ";
st.pop();
}
cout<<endl;
}