一、类模板
类模板一般声明方法如下:
template <类模板参数>class 类名{//实体}
类模板对象:类名<模板实例化参数类型>对象名(构造参数实参列表);
类名<模板实例化参数类型>对象名;
在类外面定义成员函数,必须用template重写类模板声明:
template<模板参数>
返回值类型 类名<模板类型参数>::成员函数名(函数参数列表){//函数体}
/*求最大值模板*/
#include <iostream>
using namespace std;
template <class T>
class Max4{
T a,b,c,d;
T Max(T a,T b){
return (a>b)?a:b;
}
public:
Max4(T,T,T,T); //构造函数
T Max(void); //比较四个对象大小
};
template <class T> //定义成员函数 要再次申请模板
Max4<T>::Max4(T x1,T x2,T x3,T x4):a(x1),b(x2),c(x3),d(x4){}
template <class T> //定义成员函数 要再次申请模板
T Max4<T>:: Max(void){ //要将Max4<T>看作一个整体
return Max(Max(a,b),Max(c,d));
}
int main() {
Max4<int>A(5.3,6.5,7.9,8.1);
Max4<string>B("dsf","c","fsdfsdf","fdfd");
cout<<A.Max()<<endl;
cout<<B.Max()<<endl;
return 0;
}
运行结果:
8
fsdfsdf
/*求四个对象的和*/
#include <iostream>
using namespace std;
template <class T,int size=4>
class Sum{
T m[size];
public:
Sum(T a,T b,T c,T d){
m[0]=a;
m[1]=b;
m[2]=c;
m[3]=d;
}
T S(){
return m[0]+m[1]+m[2]+m[3];
}
};
int main() {
Sum<int,4>num1(6,9,8,2);
Sum<string,4>str1("dsd","w","cv","cvb");
cout<<num1.S()<<endl;
cout<<str1.S()<<endl;
return 0;
}
运行结果:
25
dsdwcvcvb
类模板的派生与继承
模板类继承非模板类
/*模板类Line继承非模板类Point*/
#include <iostream>
using namespace std;
class Point{ //定义非模板类
int x,y;
public:
Point(int a,int b):x(a),y(b){}
void Display(){
cout<<x<<","<<y<<endl;
}
};
template <typename T>
class Line:public Point{ //Line公有继承Point
T x2,y2;
public:
Line(int a,int b,T c,T d):Point(a,b){ //构造函数
x2=c;
y2=d;
}
void display(){
cout<<x2<<","<<y2<<endl;
}
};
int main() {
Point a1(3,8);
a1.Display();
Line<float>a2(9.6,5.1,6.3,7.9);//Line为模板类 初始化 不能改变 x y的数据类型
a2.Display();
a2.display();
return 0;
}
运行结果:
3,8
9,5
6.3,7.9
模板类派生出一个模板类
/*设计一个模板类Point,然后公有派生一个模板类Line*/
#include <iostream>
using namespace std;
template <typename T>
class Point{
T x,y;
public:
Point(T a,T b){
x=a;
y=b;
}
void display(){
cout<<x<<","<<y<<endl;
}
};
template <typename T>
class Line:public Point<T>{ //公有继承模板
T x2,y2;
public:
Line(T a,T b,T c,T d):Point<T>(a,b){ //构造函数
x2=c;
y2=d;
}
void display(){
Point<T>::display();//先调用Point类的display()方法
cout<<x2<<","<<y2<<endl;
}
};
int main() {
Line<float> A(3.2,5.5,6.1,33);
A.display();
return 0;
}
运行结果:
3.2,5.5
6.1,33
二、向量
向量(vector)是一维数组的类模板,与数组相似,元素项是连续存储的,与数组不同的是,向量中存储元素的多少可以在运行中动态的增加或减少,长度不固定。
向量是类模板,具有成员函数。
向量的定义:
vector<type>name; //定义type型向量空表
vector<type>name(length); //定义具有length个type的向量,元素初始化为0
vector<type>name(length,a) //定义具有length个type的向量,元素初始化为a
vector<type>name1(name) //使用已定义的向量name构造向量name1
#include <iostream>
#include<vector>
using namespace std;
int main() {
vector<int>A(3,5);//定义3个int型向量,其它元素均为5
vector<int>B(A);//使A与B相同,有三个int型的向量,其他元素均为5
vector<char>C;
vector<char>D(2*2,'A');
vector<char>E;
E=D;
cout<<A.size()<<","<<B.size()<<","<<C.size()<<","<<D.size()<<","<<E.size()<<endl;
int IA[10]={1,5,8,45,63,21,56,54,65,96};//不能使用列表初始化一个向量,可以先初始化一个数组,然后定义
vector<int>VB(IA,IA+10); //不能用这种方法去初始化一个已经声明或定义的向量
for(int i=0;i<VB.size();i++){
cout<<VB[i]<<",";
}
return 0;
}
运行结果:
3,3,0,4,4
1,5,8,45,63,21,56,54,65,96,
泛型指针
正向泛型指针:
typedef vector<type>::iterator 泛型指针名;
逆向泛型指针:
typedef vector<type>::reverse_iterator 指针名;
#include <iostream>
#include<vector>
#include<algorithm>
#include<iterator>
using namespace std;
int main() {
vector<int>A(3,5);//定义3个int型向量,其它元素均为5
vector<int>B(A);//使A与B相同,有三个int型的向量,其他元素均为5
vector<char>C;
vector<char>D(2*2,'A');
vector<char>E;
E=D;
// cout<<A.size()<<","<<B.size()<<","<<C.size()<<","<<D.size()<<","<<E.size()<<endl;
int IA[10]={1,5,8,45,63,21,56,54,65,96};//不能使用列表初始化一个向量,可以先初始化一个数组,然后定义
vector<int>VA(IA,IA+10); //不能用这种方法去初始化一个已经声明或定义的向量
// for(int i=0;i<VA.size();i++){
// cout<<VA[i]<<",";
// }
/*使用泛型指针和copy函数*/
typedef vector<int>::iterator iterator; //正向泛型指针
typedef vector<int>::reverse_iterator reverse_iterator; //逆向泛型指针
iterator first=VA.begin();//定义正向泛型指针first,并指向向量的第一个元素位置
for(first;first<VA.end();first++){ //end是最后一个向量后一个位置
cout<<*first<<" ";
} //循环正向输出VA
cout<<endl;
copy(VA.begin(),VA.end(),ostream_iterator<int>(cout," ")); //整体正向输出VA
//编译程序时出现如下错误error: ‘ostream_iterator’ was not declared in this scope
//在头文件中加入iterator这个头文件 #include<iterator> 错误解决
cout<<endl;
reverse_iterator last=VA.rbegin(); //rbegin是最后一个向量的位置
for(last;last<VA.rend();last++){ //rend是第一个元素 前一个的位置
cout<<*last<<" ";
} //循环逆向输出VA
cout<<endl;
reverse_copy(VA.begin(),VA.end(),ostream_iterator<int>(cout," ")); //整体逆向输出VA
cout<<endl;
vector <int>VB(12);//长度为10 原样输出 ;小于10,崩溃;大于10,输出0
copy(VA.begin(),VA.end(),VB.begin());//把VA复制给VB
reverse_copy(VB.begin(),VB.end(),ostream_iterator<int>(cout," ")); //整体逆向输出VB
cout<<endl;
copy(VB.begin(),VB.end(),ostream_iterator<int>(cout," ")); //整体正向输出VA
return 0;
}
运行结果:
1 5 8 45 63 21 56 54 65 96
1 5 8 45 63 21 56 54 65 96
96 65 54 56 21 63 45 8 5 1
96 65 54 56 21 63 45 8 5 1
0 0 96 65 54 56 21 63 45 8 5 1
1 5 8 45 63 21 56 54 65 96 0 0
/*复数和结构作为向量元素的例子*/
#include <iostream>
#include<complex>
#include<vector>
using namespace std;
struct st{
int a,b;
}a[]={{2,5},{4,8}};
int main() {
complex<float>num[]={complex<float>(2,3),complex<float>(3.6,5.4)};//定义一个复数 数组
vector<complex<float>*>vnum(2); //以复数 float型指针作为向量参数
vnum[0]=&num[0];//赋值
vnum[1]=&num[1];
for(int i=0;i<2;i++){
cout<<"real:"<<vnum[i]->real()<<" imag:"<<vnum[i]->imag()<<endl;
}
vector<st *>cp(2);//以st的指针作为向量cp的参数
cp[0]=&a[0];
cp[1]=&a[1];
for(int i=0;i<2;i++){
cout<<"a:"<<cp[i]->a<<" b:"<<cp[i]->b<<endl;
}
return 0;
}
运行结果:
real:2 imag:3
real:3.6 imag:5.4
a:2 b:5
a:4 b:8
向量的操作方法
1.访问向量容量信息
size():当前存放的信息个数。
capacity():返回无需再次分配就能容纳的对象个数。
max_size():返回对象最多可以容纳的个数 max_size()>capacity()>size()
empty();若为空 返回ture 不为空 返回0
2.访问向量中对象
front():返回向量中第一个对象。
back():返回向量中的最后一个对象
operator[ ](size_type,n):返回向量中第n+1个对象
3.插入
push_back(const T&):在尾部插入
insert(inerator it,const T&):向泛型指针ti所指的位置前插入
insert(inerator it,size_type n,const T&x):向泛型指针ti所指的位置前插入n个值为x的对象
4.删除
pop_back(const T&):删除向量中最后一个对象
erase(inerator it):删除泛型指针it所指向的容器对象
clrae():删除向量中所有对象,
#include <iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<iterator>
using namespace std;
int main() {
char st[11]="abcdefghij";
vector<char>a(st,st+10),b(8);
cout<<a.size()<<" "<<a.max_size()<<" "<<a.empty()<<endl; //10 4294967295 0
for(int i=0;i<a.size();i++){
cout<<a[i]<<" ";
} //a b c d e f g h i j
cout<<endl;
for(char j='a',i=0;i<b.size();i++){
b[i]=j+i;
}
for(int i=0;i<b.size();i++){
cout<<b[i]<<" ";
} //a b c d e f g h
cout<<endl;
cout<<a.front()<<" "<<b.back()<<" "<<a.operator [](2)<<endl;//返回向量中的第一个、最后一个、第2+1个元素对象 a h c
a.pop_back();//删除最后一个元素
a.push_back('z');//在最后插入z 若插入za 只能输出a
copy(a.begin(),a.end(),ostream_iterator<char>(cout," ")); //整体正向输出a
cout<<endl;
vector<char>::iterator p;
p=a.begin();//泛型指针p指向向量a的第一个元素
a.insert(p+3, 'A');//a[3]='A'
copy(a.begin(),a.end(),ostream_iterator<char>(cout," ")); //整体正向输出a
cout<<endl;
p=a.end();//一定要给p一个位置
a.insert(p, 3, 'K');
copy(a.begin(),a.end(),ostream_iterator<char>(cout," ")); //整体正向输出a
cout<<endl;
cout<<a.size()<<" "<<a.capacity()<<endl;
p=a.begin();
a.erase(p+1); //删除b
copy(a.begin(),a.end(),ostream_iterator<char>(cout," ")); //整体正向输出a
cout<<endl;
a.clear();
cout<<a.empty();
return 0;
}
运行结果:
10 4294967295 0
a b c d e f g h i j
a b c d e f g h
a h c
a b c d e f g h i z
a b c A d e f g h i z
a b c A d e f g h i z K K K
14 20
a c A d e f g h i z K K K
1
出圈游戏:
依次输出出列人的名字
#include <iostream>
#include<vector>
#include <string.h>
#include <stdio.h>
using namespace std;
class SeqList{
char name[10];
public:
void DispName(){
cout<<name;
}
void SetName(char b[]){
strcpy(name,b);//strcpy() 复制字符串的库函数
}
void Joseph(vector<SeqList>&);
};
void SeqList::Joseph(vector<SeqList>&c){
int m,star,i,j,k;
cout<<"输入间隔数m(m<=20):"<<endl;
cin>>m;
if(m>20){
cout<<"m>20,请重新输入"<<endl;
cin>>m;
}
cout<<"从第几个人开始报数(不能大于"<<c.size()<<")"<<endl;
cin>>star;
if(star>c.size()){
cout<<"m>"<<c.size()<<",请重新输入"<<endl;
cin>>star;
}
cout<<"输入名字"<<endl;
getchar();
char s[10];
for(int i=0;i<c.size();i++){
cout<<"输入第"<<i+1<<"个人的名字:"<<endl;
gets(s);
c[i].SetName(s);
}
i=star-2;
vector<SeqList>::iterator p;
p=c.begin();
int length=c.size();
for(int k=0;k<=length;k++){
j=0;
while(j<m){
i++;
if(i==c.size()){
i=0;
}
j++;
}
if(k==length){
break;
}
c[i].DispName();
cout<<",";
c.erase(p+i);
--i;
}
c[i].DispName();
cout<<endl;
}
int main() {
int length=0;
cout<<"输入人数:";
cin>>length;
vector<SeqList>c(length);
SeqList game;
game.Joseph(c);
return 0;
}
运行结果:
输入人数:6
输入间隔数m(m<=20):
12
从第几个人开始报数(不能大于6)
2
输入名字
输入第1个人的名字:
张三
输入第2个人的名字:
李四
输入第3个人的名字:
王五
输入第4个人的名字:
赵六
输入第5个人的名字:
刘七
输入第6个人的名字:
朱八
张三,王五,李四,朱八,刘七,赵六,