2025年从零学习C++第八篇:类模板与向量

从零学习C++第八篇:类模板与向量一 类模板 类模板一般声明方法如下 template 类模板参数 class 类名 实体 类模板对象 类名 模板实例化参数类型 对象名 构造参数实参列表 类名 模板实例化参数类型 对象名 在类外面定义成员函数 模板实例化参数类型 模板实例化参数类型 类模板参数

大家好,我是讯享网,很高兴认识大家。

一、类模板

类模板一般声明方法如下:

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所指的位置前插入

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  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  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个人的名字: 朱八 张三,王五,李四,朱八,刘七,赵六,



小讯
上一篇 2025-04-05 17:29
下一篇 2025-03-13 10:38

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/61199.html