当前位置: 首页 > >

课程设计小型人员信息管理系统设计及实现

**





(按学校要求手工填写)

**

课 程 设 计 任 务 书
学院 学生姓名 设计题目 信息科学与工程学院 张昊 专业 学号 通信工程 1203060417

小型人员信息管理系统的设计与实现

内容及要求:

.小型人员信息管理系统的设计与实现
某小型公司主要有四类人员:经理、兼职技术人员、销售经理和兼职推销员。现在,需 要存储这些人员的姓名、编号、级别、当月薪水,计算月薪总额并显示全部信息。 人员编号基数为 1000,每输入一个人员信息编号顺序加 1。 程序要有对所有人员提升级别的功能。本例中为简单起见,所有人员的初始级别均为 1 级,然后进行升级,经理升为 4 级,兼职技术人员和销售经理升为 3 级,推销员认为 1 级。 月薪计算办法是:经理拿固定月薪 8000 元;兼职技术人员按每小时 100 元领取月薪; 兼职推销员的月薪按该推销员当月销售额的 4%提成; 销售经理即拿固定月薪也领取销售提 成,固定月薪为 5000 元,销售提成为所管辖部门当月销售总额的千分之五。 要求为每一类人员单独建立文件, 并在每个文件中手工录入一些人员基本信息, 并根据这些 基本信息计算职工的月薪, 并将计算结果保存入相应的磁盘文件中。 要求编写程序实现上述 功能,并且可以通过实例演示上述功能。

进度安排:

第 17 周:分析题目,查阅课题相关资料,进行类设计、算法设计; 第 18 周:程序的设计、调试与实现; 第 19 周:程序测试与分析,撰写课程设计报告,进行答辩验收
指导教师(签字) : 学院院长(签字)













2

1 需求分析.............................................................. 错误!未定义书签。 2 算法基本原理 ..................................................... 错误!未定义书签。 3 类设计.................................................................. 错误!未定义书签。 4 详细设计.............................................................. 错误!未定义书签。
4.1 类的接口设计 ...................................................................错误!未定义书签。 4.2 类的实现 ...........................................................................错误!未定义书签。 4.3 主函数设计 .......................................................................错误!未定义书签。

5 DOS 界面程序运行结果及分析 ..........................................................14
5.1 程序运行结果 ...................................................................错误!未定义书签。 5.2 运行结果分析 ....................................................................错误!未定义书签。

6 基于 MFC 的图形界面程序开发 ........................................................16
6.1 基于 MFC 的图形界面程序设计 ..................................................................... 16 6.2 程序测试 ...........................................................................错误!未定义书签。 6.3 MFC 程序编写总结 ........................................................................................... 25

7 参考文献

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·25

3

1 需求分析
(1)对小型公司做一个小型人员信息管理系统。该公司主要有四类人员:经理、 兼职技术人员、销售经理和兼职推销员。 (2)该管理系统需要存储这些人员的姓名、编号、级别、当月薪水,计算月薪 总额并显示全部信息。 (3)该系统具体要求:人员编号基数为 1000,每输入一个人员信息编号顺序加 1;对所有人员提升级别,所有人员的初始级别均为 1 级,然后进行升级, 经理升为 4 级,兼职技术人员和销售经理升为 3 级,推销员认为 1 级;经 理拿固定月薪 8000 元; 兼职技术人员按每小时 100 元领取月薪;兼职推销 员的月薪按该推销员当月销售额的 4%提成;销售经理即拿固定月薪也领 取销售提成, 固定月薪为 5000 元,销售提成为所管辖部门当月销售总额的 千分之五;要求为每一类人员单独建立文件,并在每个文件中手工录入一 些人员基本信息,并根据这些基本信息计算职工的月薪,并将计算结果保 存入相应的磁盘文件中。

2 算法基本原理
1、 定义一个员工虚基类 Employee()包含姓名、编号、级别、当月薪水四个 共有属性的数据成员;并在该虚基类基础上派生出经理 Mansger() 、兼职 技术人员 Technology () 、 销售经理 Salemansger()和兼职推销员 Salesman ()四类派生类。四种派生类分别实现各自的的员工升级、编号,添加各 自特有的数据成员并计算出各自的月薪。 (1)员工等级直接按照要求赋值即可; ( 2 ) 在 积 累 中 定 义 静 态 数 据 成 员 static int count , 并 初 始 化 int Employee::count=1000, 并在基类构造函数中实现编号的赋值 ++count; num=count; (3)派生类调用构造函数时对数据成员进行赋值,并对各种派生类输入 各自的用于计算月薪的数据成员,并按照要求计算各自的月薪。

2、 定义一个结构体链表 struct Linked,并将该链表头指针封装在友元类 Head ()中。

3、 运行时构造对象指针,并存在链表中,讲链表的头指针封装在一个友元类中。利用类中 的成员函数来实行对链表节点的打印、添加、删除以及查询。这里所以的操作均为数据结构 中对单链表的操作。

4

3 类设计
首先定义一个员工类 Employee 作为基类,由于要派生多个派生类,所以将 其定义成虚基类;然后由基类派生出四种派生类,分别是 Mansger,Technology, Salemansger 和 Salesman。 定义一个结构体链表 Linked 用来存放生成的对象指针,并将头指针封装存放在 友元类 Head 中。 基类 Employee 中的数据成员姓名、编号、等级、月薪以及一个静态变量, 静态变量用来为员工自动赋值编号,在基类构造函数中输入员工姓名,并将编号 和等级自动赋值。 派生类 Mansger 中无需添加新成员,在派生类 Technology 中添加工作时间, 在 Salemansger 中添加部门月销售额,在 Salesman 添加月销售额。派生类的功能 有输出函数 print() ,储存函数 save() ; 友元类 Head 中存放的数据成员有 Linked *top,功能有构造函数 Head() , 插入函数 Insert() ,查询函数 Check() ,删除函数 Delete() ,输出函数 print () 。 基类与各派生类之间的关系如图:
Salesman # name[20]: char # num: int # rank: int #wages: float +Employee() +print(): void -sum1 :int +Salesman () +print(): void +save(): void Technology # name[20]: char # num: int # rank: int #wages: float +Employee() +print(): void -time :int +Technology() +print(): void +save(): void Salemansger # name[20]: char # num: int # rank: int #wages: float +Employee() +print(): void -sum :int +Salemansger() +print(): void +save(): void

Employee # name[20]: char # num: int # rank: int #wages: float #count: int=1000 +Employee() +print(): void

Mansger # name[20]: char # num: int # rank: int #wages: float +Employee() +print(): void + Mansger () +print(): void +save(): void

5

Head -top: struct* +Insert(Employee *temp) +Check(): void +Delete():void +print():void

4 详细设计
整个程序分为三部分,各种职员的类,结构体链表以及封装链表的类。实现 时先生成各职员的对象指针, 之后将生成的对象指针插入到链表中,最后通过封 装类的成员函数对链表节点进行操作,最后实现对各员工的操作。

4.1 类的接口设计
#include<iostream> #include<string.h> #include<fstream> using namespace std; class Employee { protected: char name[20]; int num; int rank; float wages; static int count; public: Employee(); void print(); friend class Head; }; //基类 Employee 声明 //数据成员 //员工姓名 //员工编号 //员工登记 //员工月薪 //静态变量 //外部接口 //构造函数 //输出函数 //声明友元类

class Mansger:virtual public Employee { public: Mansger():Employee(); void print(); void save(); friend class Head; };
6

//派生类 Mansger 声明

//构造函数 //输出函数 //储存函数

class Salemansger:virtual public Employee { protected: int sum; public: Salemansger():Employee(); void print(); void save(); friend class Head; }

//派生类 Salemansger 声明

//部门销售额 //构造函数 //输出函数 //储存函数

class Technology:virtual public Employee //派生类 Technology 声明 { protected: int time; //工作时间 public: Technology():Employee(); //构造函数 void print(); //输出函数 void save(); //储存函数 friend class Head; }; class Salesman:virtual public Employee { protected: int sum1; public: Salesman():Employee(); void print(); void save(); friend class Head;; }; struct Linked { Employee *p; Linked *next; }; class Head { public: Head(); void Insert(Employee *temp);
7

//派生类 Salesman 声明

//个人销售额 //构造函数 //输出函数 //储存函数

//定义单链表

//友元类 Head 声明

//构造函数 //单链表插入函数

void Check(); void Delete(); void print(); ~Head(); private: Linked *top; };

//查找函数 //删除函数 //输出函数 //析构函数 //单链表头指针

4.2 类的实现
Employee //基类的实现 Employee ::Employee() //基类的构造函数 { cout<<"输入姓名:"; cin>>name; ++count; num=count; rank=1;} //基类成员赋值 void Employee:: print() //输出类数据成员 { cout<<"编号"<<num<<" "<<"姓名"<<name<<" "<<"等级"<<rank<<" "<<" 月薪"<<wages<<endl; } Mansger //派生类的实现 Mansger ::Mansger():Employee() //派生类构造函数 { rank=4; wages=8000; } void Mansger:: print() //输出函数 { cout<<"编号"<<num<<" "<<"姓名"<<name<<" "<<"等级"<<rank<<" "<<" 月薪"<<wages<<endl; } void Mansger ::save() //储存函数 { ofstream fs("d:\\Mansger.txt"); fs<<wages; cout<<"Mansger OK"<<endl; } Salemansger
8

//派生类的实现

Salemansger::Salemansger():Employee() //派生类构造函数 { rank=3; cout<<"输入部门销售总额:"; cin>>sum; wages=0.005*sum; } void Salemansger::print() //输出函数 { cout<<"编号"<<num<<" "<<"姓名"<<name<<" "<<"等级"<<rank<<" "<<" 月薪"<<wages<<endl; } void Salemansger::save() //储存函数 { ofstream fs("d:\\Salemansger.txt"); fs<<wages; cout<<"Salemansger OK"<<endl; } Technology //派生类的实现 Technology::Technology():Employee() //派生类的构造函数 { rank=3; cout<<"输入工作时间"; cin>>time; wages=100*time; } void Technology::print() //输出函数 { cout<<"编号"<<num<<" "<<"姓名"<<name<<" "<<"等级"<<rank<<" "<<" 月薪"<<wages<<endl; } void Technology::save() //储存函数 { ofstream fs("d:\\Technology.txt"); fs<<wages; cout<<"Technology OK"<<endl; } Salesman Salesman ::Salesman():Employee() { cout<<"输入月销售额:"; cin>>sum1;
9

//派生类的实现 //派生类的构造函数

wages=0.04*sum1; } void Salesman::print() //派生类的输出函数 { cout<<" 编号"<<num<<" "<<"姓名 "<<name<<" "<<"等级 "<<rank<<" "<<"月薪"<<wages<<endl; } void Salesman::save() //储存函数 { ofstream fs("d:\\Salesman.txt"); fs<<wages; cout<<"Salesman OK"<<endl; } Head Head::Head() { if((top=new Linked)==NULL) exit(-1); top->next=NULL; } void Head::Insert(Employee *temp) { Linked *ttop = top; while(ttop->next) ttop = ttop->next; ttop->next = new Linked; ttop->next->p = temp; ttop->next->next = 0; } void Head::Check() //链表的查找函数 { char s[20]; cout<<"输入要查找人的姓名:"; cin>>s; Linked *pbuf = top->next; while(pbuf!=NULL) { if(strcmp(pbuf->p->name,s)!=0) pbuf=pbuf->next; else if(strcmp(pbuf->p->name,s)==0) {
10

//友元类得实现 //友元类的构造函数

//链表的插入函数

cout<<" 编 号 "<<pbuf->p->num<<" "<<" 姓 "<<pbuf->p->name<<" "<<" 等 级 "<<pbuf->p->rank<<" "<<" 月 "<<pbuf->p->wages<<endl; pbuf=pbuf->next; continue; } else cout<<"查无此人"<<endl; } } void Head::Delete() //链表的删除函数 { int a; cout<<"输入要删除人的编号:"; cin>>a; Linked *pbuf = top,*q; while(pbuf->next!=NULL) if(a!=pbuf->next->p->num) pbuf=pbuf->next; else if(a==pbuf->next->p->num) { q=pbuf->next; pbuf->next=pbuf->next->next; delete q; cout<<"删除成功"<<endl; } else cout<<"查无此人"<<endl; } void Head::print() //链表的输出 { Linked *pbuf = top->next; while(pbuf!=NULL) { pbuf->p->print(); pbuf=pbuf->next; } } Head::~Head() //友元类的析构函数 { Linked *ttop,*q; ttop = top->next; while(ttop!=NULL) {
11

名 薪

q=ttop; ttop = ttop->next; delete q; } } void mnue(Head *Data) //菜单函数 { int n; cout<<"请输入 1、查找 2、删除 3、打印 0、退出:\n"; cin>>n; switch(n) { case 1: Data->Check(); //查找链表节点 break; case 2: Data->Delete(); //删除链表节点 break; case 3: Data->print(); //输出链表节点 break; case 0: break; } cout<<"是否继续(继续请按 1/退出请按 0)"; cin>>n; if(n!=0) mnue(Data); } void menu(Head *Data) { Mansger *M; Salemansger *S; Technology *T; Salesman *SA; int n; cout<<"请输入 1、经理 出:\n"; cin>>n; switch(n) { case 1: M=new Mansger; //菜单函数

//声明类指针 2、销售经理 3、技术员 4、销售员 0、退

//构造对象指针
12

M->save(); //储存对象数据 Data->Insert(M); //将对象指针插入到链表中 break; case 2: S=new Salemansger; //构造对象指针 S->save(); //储存对象数据 Data->Insert(S); //将对象指针插入到链表中 break; case 3: T=new Technology; //构造对象指针 T->save(); //储存对象数据 Data->Insert(T); //将对象指针插入到链表中 break; case 4: SA=new Salesman; //构造对象指针 SA->save(); //储存对象数据 Data->Insert(SA); //将对象指针插入到链表中 break; case 0: break; } cout<<"是否继续(继续请按 1/退出请按 0)"; cin>>n; if(n!=0) menu(Data); //递归调用 } 在类的成员函数实现过程中,派生类的构造函数使用参数调用了基类的构造 函数。在类外定义成对象指针,并用 new 生成动态内存空间来储存,并将其插 入到链表中并进行封装。 通过封装类对链表的操作从而调用各员工类中的成员函 数对各员工类进行题目所需功能的操作。

4.3 主函数设计
void main() //主函数 { Head Data; //构造对象 int n; while(1) { cout<<"请输入(1、输入 2、其他操作 0、退出) :\n"; cin>>n; switch(n) { case 1: menu(&Data); //菜单函数 1
13

break; case 2: mnue(&Data); break; case 0: system("pause"); return; } } system("cls"); }

//菜单函数 2

5 DOS 界面程序运行结果及分析

5.1 程序运行结果

对员工类进行输入操作

14

实现查找、删除以及输出功能

5.2 运行结果分析
整个程序是采用单链表的形式来储存对象指针,合理的利用的内存资源。 为了通过封装链表的类对各员工类里的成员函数进行调用,再次将该类声明 成友元类。类的外部为对象指针申请动态的储存空间,并将其插入到单链表中, 通过头结点对各个节点进行访问操作。 最后执行析构函数的时候讲点链表的节点一个一个释放掉。 利用 MFC AppWizard 创建一个基于对话框的 MFC 应用程序。 该程序使用链表类,对公司的员工信息进行输入、删除、存盘以及读取的功能
15

6 基于 MFC 的图形界面程序开发
MFC 的图形界面程序设计可在上述类设计的基础上进行改造,MFC 的图形 界面程序与 DOS 界面程序的主要不同点是:MFC 图形界面程序与 DOS 界面程 序的输入输出方式不同,DOS 界面程序采用字符交互式实现数据输入输出,主 要通过 cin,cout 等 I/O 流实现,而 MFC 的图形程序界面采用标准 Windows 窗 口和控件实现输入输出,因此必须在 MFC 类的框架下加入上面所设计的矩阵和 方程组类,并通过图形界面的输入输出改造来完成。

6.1 基于 MFC 的图形界面程序设计
(1)界面设计 首先在 VC 中建立 MFC AppWizard(exe)工程,名称为 GuassLineGUI,并在 向导的 Step1 中选择 Dialog based,即建立基于对话框的应用程序,如下图 4~5 所示。

16

将对话框资源中的默认对话框利用工具箱改造成如下界面,如图所示。

6.2 详细设计
本程序链表类对象为一结构体 CFund,它记录了姓名,编号,等级,月薪等 所有员工的信息。 struct CFund { CString m_name; //姓名 CString m_rank; //等级 float wages; //月薪
17

float income; //用于计算月薪的变量 }; 声明一个 CPtrList 型的链表类 m_fundlist。 public: Ch8Demo2Dlg(CWnd* pParent = NULL); // standard constructor CPtrList m_fundlist; 为对话框类添加一个成员函数 Resfiesh, 将链表对象中的数据在列表框显示。 void Ch8Demo2Dlg::Reflesh() { CString str,str1; m_cTheList.ResetContent (); //清空列表框 if(!m_fundlist.IsEmpty()) //链表不为空 { POSITION pos=m_fundlist.GetHeadPosition(); //获取链表头的位置 for(int i=0;i<m_fundlist.GetCount();i++) //遍历链表 { CFund *m_pFund=(CFund*)m_fundlist.GetNext(pos); str1.Format("%f",m_pFund->income); //格式化月薪 str="姓名: "+m_pFund->m_name+" 等级: "+m_pFund->m_rank+" 薪水:"+str1; m_cTheList.AddString(str); //添加列表框数据 } } UpdateData(false); //更新总量编辑框 } 对列表框类进行输入,删除的操作代码如下: void Ch8Demo2Dlg::OnCheck() { UpdateData(TRUE); CFund *m_pFund=new CFund; switch(m_radio) { case 0: if(m_name.IsEmpty()) { AfxMessageBox("用户输入不正确"); return; } m_pFund->m_name=m_name; m_pFund->m_rank="4"; //m_pFund->wages=m_wages; m_pFund->income=8000;
18

//获得编辑框数据 //创建结构体对象指针

//插入操作

m_fundlist.AddTail(m_pFund); m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; case 1:

//插入操作

if(m_name.IsEmpty()) { AfxMessageBox("用户输入不正确"); return; } m_pFund->m_name=m_name; m_pFund->m_rank="3"; m_pFund->wages=m_wages; m_pFund->income=m_wages*100; m_fundlist.AddTail(m_pFund); m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; case 2:

//插入操作

if(m_name.IsEmpty()) { AfxMessageBox("用户输入不正确"); return; } m_pFund->m_name=m_name; m_pFund->m_rank="3"; m_pFund->wages=m_wages; m_pFund->income=5000+m_wages*0.005; m_fundlist.AddTail(m_pFund); m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; case 3: //插入操作 if(m_name.IsEmpty()) {
19

AfxMessageBox("用户输入不正确"); return; } m_pFund->m_name=m_name; m_pFund->m_rank="1"; m_pFund->wages=m_wages; m_pFund->income=m_wages*0.04; m_fundlist.AddTail(m_pFund); m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; case 4: if(m_fundlist.GetCount()) { m_fundlist.RemoveHead(); } m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; case 5: if(m_fundlist.GetCount()) { m_fundlist.RemoveTail(); } m_name=" "; m_wages=0; UpdateData(false); Reflesh(); break; }

//去除表头操作

//去除表尾操作

} 为更方便使用,在操作单选按钮是设置了一下响应函数: void Ch8Demo2Dlg::OnRadio1() { UpdateData(TRUE); switch(m_radio) { case 0:
20

//单选按钮的响应函数

m_temp="nothing"; break; case 1: m_temp="工作时间"; break; case 2: m_temp="部门销售额"; break; case 3: m_temp="销售额"; break; case 4: m_temp="nothing"; break; case 5: m_temp="nothing"; break; } UpdateData(false);

} 存盘操作函数: void Ch8Demo2Dlg::OnButton2() { char szName[40]; CString strFilter,strFileName,strText; strFilter="BOOKINFO Files(*.*)|*.*||"; CFileDialog dlg(FALSE,NULL,NULL,OFN_EXPLORER|OFN_HIDEREADONLY|OFN_ENAB LESIZING|OFN_FILEMUSTEXIST,strFilter); if(dlg.DoModal()==IDOK) //显示保存 文件对话框 { strFileName=dlg.GetPathName(); // 获取文件 名 CFile m_file(strFileName,CFile::modeCreate|CFile::modeWrite); if(m_fundlist.GetCount()==0) { AfxMessageBox("数据为空!"); return; } for(int i=0;i<m_fundlist.GetCount();i++)
21

{ m_cTheList.GetText(i,strText); 框数据 strcpy(szName,strText); m_file.Write(&szName,sizeof(szName)); 据 } m_file.Close(); 对象 } } 读取函数: void Ch8Demo2Dlg::OnButton3() { char szName[40]; //记录从文件 读取的数据 CString strFilter,strFileName,strText; strFilter="BOOKINFO Files(*.*)|*.*||"; CFileDialog dlg(FALSE,NULL,NULL,OFN_EXPLORER|OFN_HIDEREADONLY|OFN_ENAB LESIZING|OFN_FILEMUSTEXIST,strFilter); if(dlg.DoModal()==IDOK) //显示打开文 件对话框 { int nvalue=MessageBox("现有数据如果没有保存将丢失,是否继续? "," 提示",4+32+256); if(nvalue==6) //用户按下了” 是”按钮 { m_cTheList.ResetContent (); //清空列表框 CString fileName=dlg.GetPathName(); CFile m_file(fileName,CFile::modeRead); int i=0; m_file.SeekToBegin(); while(m_file.Read(&szName,sizeof(szName))!=0) // 读出数据不为 空 { m_cTheList.AddString((CString)szName); } m_file.Close(); //关闭文件 } else {
22

// 获取列表

// 写文件数

//关闭文件

return; } } }

运行结果与分析
输入操作:

删除操作:

23

存盘操作:

读取操作:

24

6.3 MFC 程序编写总结
MFC 程序与 DOS 界面程序编写的最大不同是程序员需要将编程精力放在图 形界面设计、 图形界面输入输出以及界面元素和代码对应转换等问题上,而这些 问题在 DOS 界面程序中是不存在的,因此,初学 MFC 的编程者会对此感到困 难,然而,当你编写出一个基于 Windows 界面的程序时,所获得的满足程度远 远大于简单的 DOS 界面程序,况且基于 Windows 的图形界面的程序设计已成为 主流,作为程序员而言,是非学会不可的。 本次课程设计作为编写 Windows 程序的初步尝试,能够实现程序的主要功 能,可以说是取得了成功,然而好的程序绝不仅仅是只有功能性这一个指标,本 此编写的 MFC 程序虽然能实现所需功能,但从面向对象程序设计理念和图形界 面设计要求来说,尚存在不足。

7 参考文献
[1]徐士良. C 常用算法程序集. 北京:清华大学出版社,1995 [2]郑莉,董渊,张瑞丰. C++语言程序设计(第 3 版). 北京:清华大学出版社,2007 [3]钱能. C++程序设计教程(第二版). 北京:清华大学出版社,2007 [4]陈志泊,王春玲. 面向对象的程序设计语言—C++. 北京:人民邮电出版社,2002 [5]李庆扬,王能超,易大义. 数值分析. 湖北:华中理工大学出版社,1986

25




友情链接: year2525网 工作范文网 QS-ISP 138资料网 528200 工作范文网 baothai 表格模版