功能简要:
班级信息管理系统
能添加删除学生,查询学生信息
管理指定学生课程,包括添加课程,删除课程
查询某个学生某门课的成绩
统计任意学生的总学分
其他功能:
按学号/总成绩/总学分降序排列学生
student类:
student.h:
#pragma once
#include"student.h"
class manage
{
public:
manage();
~manage();
void Add(const student& stu);
void Del(const student& stu);
void Search(const string& studentname);
void DisplayAll();
void Sort(int num);//排序函数
static bool Compare_Num(const student& s1, const student& s2); //这三个函数为排序的标准
static bool Compare_TotalGrade(const student& s1, const student& s2);
static bool Compare_TotalCred(const student& s1, const student& s2);
vector<student>::iterator& IsNameSame(const string& studentname);
private:
vector<student> Student;
vector<student>::iterator ptr;
};
student.cpp
#include "stdafx.h"
#include "student.h"
#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<ctime>//time()
#include<Windows.h>//sleep()
student::student()
{
ptr = Lesson.begin();
}
void student::AddLesson(const lesson& les)
{
if (!this->IsLessonNull(les))
{
if (Lesson.end() == this->IsNameSame(les.lessonname))
this->Lesson.push_back(les);
else
cout << "the lessonname has exist!" << endl;
}
else
cout << "please input all the information!" << endl;
this->TotalCred = CalcTotalCred();
this->TotalGrade = CalcTotalGrade();
}
void student::DelLesson(const string& name)
{
if (!this->Lesson.empty())
{
vector<lesson>::iterator ptr = this->IsNameSame(name);
if (ptr != Lesson.end())
Lesson.erase(ptr);
else
cout << "no lessonnames match!" << endl;
}
else
cout << "the lessons is null" << endl;
this->TotalCred = CalcTotalCred();
this->TotalGrade = CalcTotalGrade();
}
vector<lesson>::iterator& student::IsNameSame(const string& name)
{
for (ptr = Lesson.begin(); ptr != Lesson.end(); ptr++)
{
if (ptr->lessonname == name)
return ptr;
}
return ptr;
}
bool student::IsLessonNull(const lesson& les)
{
if (les.lessonname.empty()|| les.credit == 0)
return 1;
else
return 0;
}
int student::SearchGrade(const string& les)
{
vector<lesson>::iterator ptr = this->IsNameSame(les);
if (Lesson.end() != ptr)
return ptr->grade;
else
return -1;
}
int student::CalcTotalCred()
{
int total = 0;
if (!Lesson.empty())
{
for (ptr = Lesson.begin(); ptr != Lesson.end(); ptr++)
total += ptr->credit;
return total;
}
else
return -1;
}
int student::CalcTotalGrade()
{
int total = 0;
if (!Lesson.empty())
{
for (ptr = Lesson.begin(); ptr != Lesson.end(); ptr++)
total += ptr->grade;
return total;
}
else
return -1;
}
void student::print()
{
//设定字符宽度为10
cout <<setw(10)<< "姓名" << setw(10)<<"年龄" << setw(10)<<"学号" << endl;
cout << "----------------------------------" << endl;
cout << setw(10) << this->Name << setw(10) << this->Age << setw(12) << this->Num << endl;
cout << endl;
cout << endl;
cout << setw(10) << "课程" << setw(10) << "成绩" << setw(10) << "学分" << endl;
cout << "----------------------------------" << endl;
if (!Lesson.empty())
{
ptr = Lesson.begin();
for (ptr; ptr != Lesson.end(); ptr++)
cout << setw(10) << ptr->lessonname << setw(10) << ptr->grade << setw(10) << ptr->credit << endl ;
cout << "TotalGrade: " << this->TotalGrade <<endl<< "TotalCred: " << this->TotalCred << endl;
cout << endl;
}
else
cout <<setw(10)<< "NULL" << endl;
}
void student::clear()
{
Lesson.clear();
}
void student::rand()
{
lesson S1, S2, S3;
srand((unsigned)time(NULL));//设置随机数种子,时间为系统时间
Sleep(1000); //防止短时间内连续调用种子不变,延时一秒
int Number_grade[3];
int Number_cred[3];
for (int i = 0; i < 3; i++)
{
Number_grade[i] = ::rand() % 51 + 50;
Number_cred[i] = ::rand() % 6 + 1;
}
S1 = { "Math", Number_grade[0], Number_cred [0]};
S2 = { "ENGLISH", Number_grade[1], Number_cred[1] };
S3 = { "PHYSICS", Number_grade[2], Number_cred [2]};
Lesson.push_back(S1);
Lesson.push_back(S2);
Lesson.push_back(S3);
}
student::~student()
{
}
manage类:
manage.h:
#pragma once
#include"student.h"
class manage
{
public:
manage();
~manage();
void Add(const student& stu);
void Del(const student& stu);
void Search(const string& studentname);
void DisplayAll();
void Sort(int num);//排序函数
static bool Compare_Num(const student& s1, const student& s2); //这三个函数为排序的标准
static bool Compare_TotalGrade(const student& s1, const student& s2);
static bool Compare_TotalCred(const student& s1, const student& s2);
vector<student>::iterator& IsNameSame(const string& studentname);
private:
vector<student> Student;
vector<student>::iterator ptr;
};
manage.cpp
#include "stdafx.h"
#include "manage.h"
#include<iostream>
#include<algorithm>//sort()
using namespace std;
manage::manage()
{
ptr = Student.begin();
}
void manage::Add(const student& stu)
{
ptr = this->IsNameSame(stu.Name);
if (ptr == Student.end())
Student.push_back(stu);
else
cout << "name repeated!" << endl;
}
void manage::Del(const student& stu)
{
if (!Student.empty())
{
ptr = this->IsNameSame(stu.Name);
if (ptr != Student.end())
Student.erase(ptr);
else
cout << "no studentname matches" << endl;
}
else
cout << "student's list is null" << endl;
}
void manage::Search(const string& studentname)
{
if (!Student.empty())
{
ptr = this->IsNameSame(studentname);
if (ptr != Student.end())
ptr->print();
else
cout << "no studentname matches" << endl;
}
else
cout << "student's list is null" << endl;
}
void manage::DisplayAll()
{
if (!Student.empty())
{
for (ptr = Student.begin(); ptr != Student.end(); ptr++)
{
ptr->print();
cout << "********************************" << endl;
}
}
else
cout << "no informations!" << endl;
}
vector<student>::iterator& manage::IsNameSame(const string& studentname)
{
for (ptr = Student.begin(); ptr != Student.end(); ptr++)
{
if (ptr->Name == studentname)
return ptr;
}
return ptr;
}
bool manage::Compare_Num(const student& s1, const student& s2)
{
return s1.Num > s2.Num;
}
bool manage::Compare_TotalGrade(const student& s1, const student& s2)
{
return s1.TotalGrade > s2.TotalGrade;
}
bool manage::Compare_TotalCred(const student& s1, const student& s2)
{
return s1.TotalCred > s2.TotalCred;
}
void manage::Sort(int num = 0)
{
switch (num)
{
case 0:
sort(Student.begin(), Student.end(), Compare_Num); break;
case 1:
sort(Student.begin(), Student.end(), Compare_TotalGrade); break;
case 2:
sort(Student.begin(), Student.end(), Compare_TotalCred); break;
}
}
manage::~manage()
{
}
主函数:
// Info.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "student.h"
#include "manage.h"
#include <cstdlib>
#include<iostream>
int _tmain(int argc, _TCHAR* argv[])
{
student s1("zhang","22","14552613");//创建学生
student s2("liu","23","14551515");
student s3("ans","25","14552711");
s1.print();//打印学生信息
s2.print();
s3.print();
lesson les = { "PSYCHOLOGY", 88, 3 };//创建课程
s1.AddLesson(les);//添加课程
s2.DelLesson("ENGLISH");//删除课程
s3.clear();//清空课程
s1.print();
s2.print();
s3.print();
cout << s1.SearchGrade("Math") << endl;//查询某门课成绩
s3 = student("wang", "35", "14551326");
manage m1;//创建学生列表
m1.Add(s1);//添加学生进列表
m1.Add(s2);
m1.Add(s3);
m1.DisplayAll();//打印所有学生信息
m1.Sort(1);//0:按学号降序,1:按总成绩降序,2:按总学分降序
m1.DisplayAll();
m1.Search("wang");//搜索某学生信息
m1.Del(s2);//删除某学生
m1.DisplayAll();
system("pause");
return 0;
}
出现问题:
1 当两个类的头文件互相包含对方的类头文件时编译报错:
解决: 如果classa.h 与 classb.h互相包含对方头文件,则在classa.h头文件里不用#include"classb.h>,而是改为class classb;
告诉编译器会用到类classb.当然也可以在classb.h里写class classa.
2 当普通对象(LinkedList list)访问常成员函数时,普通对象会自动转为常对象(cont LinkedList list);常对象只能访问常成员函数。
例如:
class LinkedList
{
private:
public:
void showElement()const;
bool endOfList();
int data();
};
void LinkedList::showElement()const
{
//输出各点数据,直到链表尾
while( !endOfList())
{
cout << data() << " " ;
next();
}
}
#include <iostream>
using namespace std;
int main(void)
{
LinkedList list; //list为非常对象
list.showElement(); //C++语法:非常对象访问常成员函数时会自动转成常对象
return 0;
}
来自:http://blog.csdn.net/qq2399431200/article/details/12884861
首先定义了list对象,是非常对象,调用了const函数showElement() const后,转为const对象,可是在const函数内部,对象又需要调用非const函数endOflist()根据以上规则,故出错;
解决:1 将showElement() const声明为普通函数或者将该函数里调用的函数都声明为const函数
2 定义两个函数版本const与非const,在从重载运算符中常用到
3 关于友元类
当一个类B成为了另外一个类A的“朋友”时,那么类A的私有和保护的数据成员就可以被类B访问
声明友元类的方法其实很简单,只要我们在类A的成员列表中写下如下语句:friend class B;
4 要想让类成员函数作为参数,则必须为静态函数,static
5 vector排序
包含#include<algorithm>
调用sort(),三个参数,前两个为排序的范围,后一个为排序的标准,一般自定义一个函数,告诉sort()怎么比较算小,因为sort默认以升序排列。
6 随机数的产生
该程序中用随机数的方式初始化课程成绩:
随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就不会变。
srand((unsigned)time(NULL));//设置随机数种子,时间为系统时间
Sleep(1000); //防止短时间内连续调用种子不变,延时一秒
time()函数返回从Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。返回值为time_t为int64,包含ctime头文件
测试:
int _tmain(int argc, _TCHAR* argv[])
{
cout << sizeof(int) << endl;
cout << sizeof(time_t)<<endl;
cout << time(0) << endl;
system("pause");
return 0;
}
结果:
4
8
1497711361
请按任意键继续. . .
1497711361s = 47.46年 = 47年5月15天14小时24分
加上1970 年 1 月 1 日 00:00:00 = 2017年6月16日14小时24分 ,中国比其快8小时,最后为22小时24分,不考虑平闰年月的因素,基本一致。
因此每次运行该exe程序都会得到不同的数,
如果不用time()做种子的话,如srand(5),则每次打开exe,都生成相同数字。
但本程序中可能会出现连续调用三次srand()函数的情况,而每次的间隔不可能达到一秒钟,这样的话相当于每次设置了同样的种子。
因此解决方案:
sleep(1000) 暂停进程一秒 ,包含在window.h
或者设置标志位使该函数只运行一次
7 设置宽度:
setw(10) 包含在#include<iomanip>,跟width()一样,每次只对下一次输出有效,但比方便,可以直接cout<<setw(10)<<cout.....
而width需要另外cout.width(10)设置
8 初始化成员列表的方法
student(string name, string age, string num) :Name(name), Age(age), Num(num)
{
ptr = Lesson.begin();
this->rand(); TotalCred = CalcTotalCred(); TotalGrade = CalcTotalGrade();
};