ZSTU_cpp2_多态性实验

ZSTU_cpp2_多态性实验

一、实验目的

1.理解重载运算符的意义。

2.掌握使用友元函数重载运算符的特点。

3.掌握重载运算符函数的调用方法。

4.掌握动态联编的概念。

5.掌握虚函数和纯虚函数的使用方法。

二、实验原理介绍

设计性实验

具体原理请见实验内容和步骤

实现对抽象类的继承,通过operator函数调用的形式,实现运算符的重载

三、实验设备介绍

软件需求: Visual Studio C++或Codeblocks或Dev C++或其他C++ IDE

硬件需求: 能够流畅运行C++ IDE的计算机一台。

四、实验内容

某大学班级有本科生CStudent、留学生FStudent,他们的绩点计算方法如下:

​ 本科生绩点计算方法是: 英语0.03+数学0.04+计算机*0.03。

留学生绩点计算方法: 中文0.03+数学0.04+计算机*0.03。

成绩均为百分制,绩点总计10。

每类学生都有学号、姓名、性别、年龄、类别等数据,类别分为本科生和留学生,各类人员使用统一接口getPoint()计算各类人员的绩点,重载<<运算符实现学生信息的输出。其次,设计一个统计并输出该班级每个人员绩点信息的报表类Report,该类提供insert接口向Report类的容器中添加学生信息,并提供print接口用于输出所有学生的学号、姓名、性别、年龄和绩点。为了方便实现查找功能,为Report类重载[]运算符的功能,下标值为学生类别,能根据类别查找出所有该类别的学生,并重载print接口,输出指定类别的学生信息。初始成绩表里可以先固定添加4个本科生和4个留学生信息。各个指令和对应功能如下:

指令1:输入学号,删除相应记录;

指令2:删除所有学生的记录;

指令3:分类别显示所有学生绩点记录表;

指令4:输入类别,显示该类别学生绩点记录表;

指令-1:退出。

五、注意事项和要求

要求学生要提前准备实验的内容

实验完成后要求写出实验报告

coding

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include<bits/stdc++.h>
#include"student.h"
#include"Report.h"
// #define 留学生 FStudent
// #define 本科生 CStudent
using namespace std;


int menu(){
int temp;
cout<<endl;
cout<<"-----------------------学生绩点系统-----------------------"<<endl;
cout<<"----------------------------------------------------------"<<endl;
cout<<"----"<<setw(20)<<"输入 1: 输入学号并删除相应记录 "<<endl;
cout<<"----"<<setw(20)<<"输入 2: 删除所有学生的记录 "<<endl;
cout<<"----"<<setw(20)<<"输入 3: 分类别显示所有学生绩点记录表 "<<endl;
cout<<"----"<<setw(20)<<"输入 4: 输入类别并显示该类别学生绩点记录表 "<<endl;
cout<<"----"<<setw(20)<<"输入 5: 输入学生信息插入至学生绩点记录表 "<<endl;
cout<<"----"<<setw(20)<<"输入-1: 退出 "<<endl;
cout<<"----------------------------------------------------------"<<endl;
cin>>temp;
return temp;
}
Report *init(){
Report *temp=new Report;
try{

(*temp).insert((student*)new CStudent(101,"李博"s,"男"s,21,"CStudent"s,95,91,80));
(*temp).insert((student*)new CStudent(102,"李欣"s,"女"s,20,"CStudent"s,100,100,99));
(*temp).insert((student*)new CStudent(103,"李蓉"s,"女"s,20,"CStudent"s,100,99,99));
(*temp).insert((student*)new CStudent(104,"黄黄"s,"男"s,21,"CStudent"s,80,99,60));

(*temp).insert((student*)new FStudent(1001,"EaKal"s,"男"s,21,"FStudent"s,80,99,60));
(*temp).insert((student*)new FStudent(1002,"Rolemee"s,"男"s,20,"FStudent"s,90,99,70));
(*temp).insert((student*)new FStudent(1003,"Bazingaa"s,"女"s,18,"FStudent"s,95,99,90));
(*temp).insert((student*)new FStudent(1004,"Elagal"s,"男"s,23,"FStudent"s,80,99,60));
}
catch(const char* msg){
cout<<msg<<endl;
}
// catch(...){
// cout<<"50错误"<<endl;
// }

return temp;
}
int main(){
Report *stu=init();
while(1){
switch (menu())
{
case 1:
int sno;
cout<<"请输入您要删除的学号"<<endl;
cin>>sno;
try{stu->delete_once(sno);}
catch(const char* msg){
cout<<msg<<endl;
}
break;
case 2:
stu->delete_all();
cout<<"删除所有记录成功!"<<endl;
break;
case 3:
try{
stu->print("CStudent");
stu->print("FStudent");
}
catch(const char* msg){
cout<<msg<<endl;
}
break;
case 4:
try{
string Select;
cout<<"请输入你想要输出的类别"<<endl;
cin>>Select;
if(Select=="本科生"s){
Select="CStudent"s;
}else if(Select=="留学生"s){
Select="FStudent"s;
}
stu->print(Select);
}
catch(const char* msg){
cout<<msg<<endl;
}
break;
// case 5:
// try{
// student *a=new student;
// stu->insert(*a);
// }
// catch(const char* msg){
// cout<<msg;
// }
// break;
case -1:
exit(0);
default:
break;
}
}
return 0;
}

student.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#pragma once
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

class student
{
friend ostream &operator<<(ostream &os,student &student);
private:
int sno;
string name;
string sex; // 1 man 0 female
int age;
string kind; //1 CStudent 0 Fstudent
int score_math;
int score_cs;
public:
student(int sno,string name,string sex,int age, string kind,int score_math,int score_cs);
student();
~student();
virtual float getPoint()=0;
bool getkind();
int getsno();
int getscore_math();
int getscore_cs();
};

class CStudent:student{
private:
int score_en=0;
public:
CStudent(int sno,string name,string sex,int age, string kind,int score_math,int score_cs,int score_en);
virtual float getPoint();
};

class FStudent:student{
private:
int score_cn;
public:
FStudent(int sno,string name,string sex,int age, string kind,int score_math,int score_cs,int score_cn);
virtual float getPoint();

};
bool cmp(student* temp1,student *temp2);

student.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<bits/stdc++.h>
#include"student.h"
using namespace std;
bool cmp(student* temp1,student *temp2){
return temp1->getsno()<temp2->getsno();
}

student::student(int sno,string name,string sex,int age, string kind,int score_math,int score_cs):sno(sno),name(name),sex(sex),age(age),kind(kind),score_math(score_math),score_cs(score_cs)
{
if(sex!="男"s && sex!="女"s)
throw "创建失败,性别有误";
if(kind!="CStudent"s && kind!="FStudent"s)
throw "创建失败,类别有误";
}

student::~student()
{
}
ostream &operator<<(ostream &os,student &student){
os<<setw(10)<<student.sno<<setw(10)<<student.name<<setw(10)<<student.sex<<setw(10)<<student.age<<setw(10)<<student.getPoint()<<endl;
return os;
}
bool student::getkind(){
return kind=="CStudent"s;
}
int student::getsno(){
return sno;
}


FStudent::FStudent(int sno,string name,string sex,int age, string kind,int score_math,int score_cs,int score_cn):student(sno,name,sex,age,kind,score_math,score_cs),score_cn(score_cn)
{

}
CStudent::CStudent(int sno,string name,string sex,int age, string kind,int score_math,int score_cs,int score_en):student(sno,name,sex,age,kind,score_math,score_cs),score_en(score_en)
{

}
int student::getscore_math(){
return score_math;
}
int student::getscore_cs(){
return score_cs;
}

float FStudent::getPoint(){
return getscore_math()*0.04+getscore_cs()*0.03+score_cn*0.03;
}
float CStudent::getPoint(){
return getscore_math()*0.04+getscore_cs()*0.03+score_en*0.03;
}

Report.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include<bits/stdc++.h>
#include"Report.h"
#include"student.h"
using namespace std;

void Report::insert(student* a){
for(auto b:ptr){
if((b)->getsno()==a->getsno())
throw"Oops!The same Sno!";
}
(ptr).push_back(a);
}

Report* Report::operator[](string index){
vector<student*>::iterator it = ptr.begin();
Report *temp1=new Report;
// Report temp2;
if(index=="CStudent"s){
for (; it != ptr.end();++it)
{
try{
if((*it)->getkind())
temp1->insert((*it));
}
catch(const char* temp){ //其实这里不可能抛出异常我也不知道我为什么要写G
cout<<temp<<endl;
}
}
}else{
for (; it != ptr.end();++it)
{
try{
if(!(*(*it)).getkind())
temp1->insert((*it));
}
catch(const char* temp){
cout<<temp<<endl;
}

}
}
return temp1;
}
void Report::delete_all(){
ptr.clear();
}

void Report::print(string i){
sort(ptr.begin(),ptr.end(),cmp);
if(i!="CStudent"s&&i!="FStudent"s)
throw("请输入正确的类别!");
// vector<student>::iterator it = ++(*this)[i].ptr.begin();
Report *temppp=(*this)[i];
if((temppp)->ptr.empty()){
cout<<((i=="CStudent"s)?"本科生":"留学生")<<"无人!"<<endl;
return ;
}
double max=0;
double min=10;
cout<<"----------------------------------------------------------"<<endl;
cout<<"--------------------------"<<((i=="CStudent"s)?"本科生":"留学生")<<"--------------------------"<<endl;
// for (; it != (*this)[i].ptr.end();++it){
// cout<<(*it)<<endl;
// if((*it).getPoint()>max) max=(*it).getPoint();
// if((*it).getPoint()<min) min=(*it).getPoint();
// }
for(auto tttemp:temppp->ptr){
cout<<(*tttemp)<<endl;
if((*tttemp).getPoint()>max) max=(tttemp)->getPoint();
if((*tttemp).getPoint()<min) min=(tttemp)->getPoint();
}
cout<<"最高绩点:"<<max<<endl;
cout<<"最低绩点:"<<min<<endl;
cout<<"----------------------------------------------------------"<<endl;
}

void Report::delete_once(int sno){
bool flag=false;
for(auto it=ptr.begin();it!=ptr.end();++it)
{
if((*(*it)).getsno()==sno)
{
it=ptr.erase(it);
flag=true;
}
}
if(!flag)
throw("查无此人");
else{
cout<<"删除学号为:"<<sno<<"记录成功"<<endl;
}
}



Report.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include<bits/stdc++.h>
#include"student.h"
using namespace std;

class Report{
// student& operator[](int index){
// return
// }
private:
vector<student*> ptr;
public:
Report *operator[](string);
void insert(student* a);
void delete_all();
void print(string i);
void delete_once(int sno);
};


THINK

这个实验就是对于多态的一个训练,相当简单,大部分操作与stl中的vector相同,直接上手就行了.


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!