小型人员信息管理系统
成 绩 评 定 表
课程设计任务书
摘 要
C++是支持面向过程的设计,更是支持基于对象和面向对象的程序设计。类是C++中十分重要的概念,它是实现面向对象程序设计的基础。本文采用虚基类及其派生类实现了对小型人员信息的管理,类的封装性和信息隐蔽性可以很好的保护公司员工的信息,同时采用了Visual C++ 6.0的控制台工程和MFC 工程实现了对员工基本信息的输入和全部信息的输出及保存。
关键词:信息管理;类;控制台工程;MFC 工程
目 录
1 需求分析 .............................................................................................................................. 1 2 算法基本原理 ...................................................................................................................... 1 3 类设计 .................................................................................................................................. 2 4 基于控制台的应用程序 ...................................................................................................... 3 4.1 类的接口设计 ............................................................................................................... 4 4.2 类的实现 ....................................................................................................................... 7 4.3 主函数设计 ................................................................................................................. 11 4.4 基于控制台的应用程序测试 ..................................................................................... 12 5 基于MFC 的应用程序 ........................................................................................................ 14 5.1 基于MFC 的应用程序设计 ......................................................................................... 15
5.1.1 MFC程序界面设计 . ........................................................................................................... 15 5.1.2 MFC程序代码设计 . ......................................................................................................... 16
5.2基于MFC 的应用程序测试 . ........................................................................................... 21 结 论 ........................................................................................................................................ 23 参考文献 .................................................................................................................................. 24
1 需求分析
(1)对小型公司进行小型人员信息操作管理系统。该公司主要有四类人员:经理、销售经理、兼职技术人员、兼职推销员;定义一个虚基类并且派生四个子类。
(2)系统需要存储这些人员的姓名、编号、级别、当月薪水,输入基本信息,计算月薪总额,显示并保存全部信息;每个派生类的构造函数要实现对其特有数据成员的初始化。
(3)系统具体要求:
①编号要求:人员编号基数为1000,每输入一个员工姓名编号加1;编号定义为全局静态变量即可。
②级别要求:所有人员的初始级别均为1级,然后进行升级,经理升为4级,兼职技术人员和销售经理升为3级,兼职推销员为1级;直接对级别赋值即可。
③月薪要求:经理拿固定月薪8000元;兼职技术人员按每小时100元领取月薪;兼职推销员的月薪按该推销员当月销售额的4%提成;销售经理既拿固定月薪也领取销售提成,固定月薪为5000元,销售提成为所管辖部门当月销售总额的千分之五。
④总体要求:为每一类人员单独建立文件,并在每个文件中手工录入一些人员基本信息,并根据这些基本信息计算职工的月薪,并将计算结果保存入相应的磁盘文件中。
2 算法基本原理
(1)定义一个员工虚基类Employmee( ) ,包括员工姓名、级别、编号月薪共有的基本数据成员;
(2)在基类的基础上派生出经理Mansger( )类、销售经理Salemansger( )类、兼职技术人员Technology( )类和兼职推销员Saleman( )类,并在这四个派生类中添加各自数据成员和成员函数。具体分析如下:
①员工编号的可以定义全局静态变量static int count=0;并且初始化员工编号number=1000+count;每输入一个员工的姓名编号加1。
②员工等级按照要求直接赋值即可;
③在派生类的构造函数中初始化数据成员并且按照要求计算各成员的月薪。
(3)定义一个结构体链表struct Linked,并将链表的头指针头封装在友元类Head( )中。
(4)运行时构造对象指针,并存在链表中,利用类中的成员函数来实现对链表节点的打印、添加、保存。这些操作均作为数据结构中对单链表的操作。
3 类设计
首先定义一个员工基类Employee ,由于要派生出多个子类,所以将其定义为虚基类;在类外定义全局静态变量,用于记录员工的编号。虚基类Employee 中的数据成员包括姓名、编号、等级、月薪。虚基类的成员函数包括打印函数 printf( ),并声明友元类。
然后派生出经理Mansger 类、销售经理Salemansger 类、兼职技术人员Technology 类和兼职推销员Saleman 类。在派生类Mansger 的构造函数直接对月薪和等级赋值:月薪8000,等级4;在派生类Salemansger 的构造函数中定义特有的数据成员:销售总额sum1,并根据要求计算月薪,等级赋值3;在派生类Technology 的构造函数中定义特有的数据成员:工作时间time ,并根据要求计算月薪,等级赋值3;在派生类Saleman 的构造函数中定义特有的数据成员:销售额sum2,并根据要求计算月薪,等级赋值1。派生类的功能有打印函数 printf( ),储存函数save( )。
友元类Head 存放的数据成员有Linked top,功能有构造函数Head( )、插入函数Insert( )、打印函数printf( )以及析构函数~Head( );其中功能构造函数用来开辟储存空间,插入函数采用单链表现实信息的输入,打印函数用来输出录入员工的全部信息,析构函数用来释放空间。
基类与各派生类之间的关系如下图所示:
图1 Employee类和其派生类关系的图形表示
在程序实现过程中,各派生类的成员函数需要访问基类Employee 的数据成员,利用公有继承方式派生,同时将Employee 类中的数据成员的访问控制设置为保护类型。这样,经过公有派生之后,基类的保护成员在派生类中依然是保护成员,可以被派生类的成员函数访问。
4 基于控制台的应用程序
整个程序分为三部分,各种职员的类,结构体链表以及封装在结构体链表的类。实现时先生成各种职员的对象指针,之后将生成的对象指针插入到链表中,最后通过封装类类的成员函数对链表节点进行操作,实现对员工的操作。
4.1 类的接口设计
#include #include #include using namespace std;
static int count=0; //全局动态变量,用于记录员工编号 //定义虚基类
class Employee {public:
Employee() //构造函数,初始化员工基本信息
{ cout
cin>>name;
++count;
number=count+1000;
level=1;
}
void printf(); //打印函数 friend class Head; //声明友元类
protected: //数据成员为保护类型
char name[30]; int number; int level; float wages;
};
//派生类Mansger
class Mansger: public virtual Employee { public:
Mansger():Employee(){level=4;wages=8000;} //构造函数定义
void save(); //储存函数 void printf(); //打印函数
friend class Head; //声明友元类 }; //派生类Salemansger
class Salemansger: public virtual Employee {public:
Salemansger():Employee() //构造函数定义 {level=3; cout>sum1;
wages=5000+0.005*sum1; }
void save (); void printf(); friend class Head; protected:
int sum1; };
//派生类Technology
class Technology: public virtual Employee {public:
Technology():Employee() {level=3;
cout>time;
wages=100*time; }
void save(); void printf();
friend class Head;
protected:
float time; };
//派生类Saleman
//计算销售经理工资//储存函数 //打印函数 //销售总额 //构造函数定义 //计算技术人员工资 //储存函数 //打印函数 //工作时间
class Saleman: public virtual Employee / {public:
Saleman():Employee() //构造函数定义 {level=1;
cout>sum2;
wages=0.04*sum2; //计算销售员工资 }
void save (); //储存函数 void printf(); friend class Head; protected:
int sum2; //销售总额 };
//定义友元类
class Head {public:
Head(); //构造函数
void Insert(Employee*temp); //单链表的插入函数 void printf(); //打印函数 ~Head(); //析构函数
private:
Linked*top; //单链表的头结点
};
经过公有派生,四个派生类获得了除构造函数之外的Employee 类的全部成员,由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基类继承来的成员全部可以访问,而对于建立派生类对象的外部模块来讲,基类的保护成员是无法访问的。通过保护访问类型和公有的继承方式,实现了基类Employee 的数据的有效共享和可靠保护。友元类可以实现外部函数对类中数据成员的调用,在程序中,员工的基本信息的输入,全部信息的保存都是在基类、派生类的构造函数以及友元类的成员函数中完成,它们的清理工作在友元类析构函数中完成。
4.2 类的实现
//基类输出函数
void Employee::printf()
{cout
//派生类Mansger 输出函数
void Mansger::printf()
{cout
//派生类Mansger 储存函数
void Mansger::save() {ofstream fs("f:\\Mansger.txt");
fs
//派生类Salemansger 输出函数 void Salemansger::printf()
{cout
//派生类Salemansger 储存函数 void Salemansger::save()
{ofstream fs("f:\\Salemansger.txt");
fs
"
//派生类Technology 输出函数 void Technology::printf()
{cout
//派生类Technology 储存函数 void Technology::save()
{ofstream fs("f:\\Technology.txt");
fs
//派生类Saleman 输出函数
void Saleman::printf() {
{cout
//派生类Saleman:储存函数 void Saleman::save()
{ofstream fs("f:\\Saleman.txt");
fs
//友元类的实现
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::printf() { Linked*pbuf=top->next; while(pbuf!=NULL) { pbuf->p->printf(); pbuf=pbuf->next;
}
}
//链表的析构函数 Head::~Head() { Linked*ttop,*q; ttop=top->next; while(ttop!=NULL) { q=ttop; ttop=ttop->next;
delete q; }
}
//菜单函数
void menu(Head*Data) { int n; cout
cin>>n;
//插入打印函数 //释放空间 0、退出:";
switch(n) //多分支选择语句
{case 1:
Data->printf(); //输出链表节点
break;
case 0: break;
}
cout>n; if(n!=0)
menu(Data); //递归调用 }
//菜单函数1
void menu1(Head*Data)
{ Mansger*M; //声明类指针 Salemansger*S; Technology*T; Saleman*S1; int n;
cout>n; switch(n) { case 1: M=new Mansger; //构造对象指针 M->save(); //储存对象数据
Data->Insert(M); //将对象指针插入到链表中
break;
case 2: S=new Salemansger; //构造对象指针
S->save(); //储存对象数据
0、
}
break;
case 3:
T=new Technology; //构造对象指针 T->save(); //储存对象数据
Data->Insert(T); //将对象指针插入到链表中 break;
case 4:
S1=new Saleman; //构造对象指针 S1->save(); //储存对象数据
Data->Insert(S1); //将对象指针插入到链表中 break;
case 0:
break;
cout>n;
if(n!=0)menu1(Data); //递归调用
}
在类的成员函数实现过程中,派生类的成员函数调用了基类的构造函数,只是整个调用过程中完全是由系统内部完成。基类的保护数据成员,经过公有派生之后,在派生类中是以保护成员的身份出现的,派生类的成员函数可以自由地进行访问。通过定义友元类访问类内的保护成员,并通过单链表法开辟输入空间以便插入员工的信息。最后通过友元类的析构函数释放空间。
4.3 主函数设计
//主函数
void main()
{ Head Data; //构造对象 int n; while(1)
}
}
system("cls");
cin>>n;
switch(n) //多分支语句进行菜单的选择 {case 1:
menu1(&Data); break;
case 2:
menu(&Data); break;
case 0: }
system("pause"); return;
在程序的主函数部分,定义一个构造对象以便实现调用。Switch 多分支选择语句可以选择菜单从而实现输入、打印操作。
4.4 基于控制台的应用程序测试
程序运行结果如图2-1和2-2所示。
图2-1 程序运行结果
1
图2-2 程序运行结果2
为每类员工保存的文件夹如图3-1所示的Mansger.txt 、Salemansger.txt 、Saleman.txt 、Technology.txt :
图3-1存盘文件夹
为经理建立的文件夹打开后如图3-2所示:
图3-2显示经理文件夹
为销售经理建立的文件夹打开后如图3-3所示:
图3-3显示销售经理文件夹
为兼职技术人员建立的文件夹打开后如图3-4所示:
图3-4显示兼职技术人员文件夹
为兼职推销员建立的文件夹打开后如图3-5所示:
图3-5显示兼职推销员文件夹
从图2-1到3-5可以看出,在DOS 界面通过对菜单的选择可以输入和打印员工的信息。经理只需要输入姓名,销售经理要输入姓名和当月的部门的销售总额,兼职技术人员要输入姓名和工作时间,兼职推销员要输入姓名和月销售额,然后选择打印菜单即可输出各类人员的全部信息,而这些信息已经通过程序的文件输出流以TXT 的格式保存在了电脑磁盘F:\梁庶芹文件夹中。打开后便可显示各类员工的全部信息。
5 基于MFC 的应用程序
MFC 是通过窗口和控件实现输入输出,设置MFC 界面也很重要,界面的美观程度直接影响了程序设计的好坏。下面在MFC 类的框架下加入上述类并实现人员的信息管理,通过图形界面的输入和输出。
5.1 基于MFC 的应用程序设计
5.1.1 MFC程序界面设计
首先在VC 中建立MFC AppWizard (exe )工程,名称为lsq ,并在向导的Step1中选择Dialog based,即建立基于对话框的应用程序,如下图4~1和4-2所示。
图4-1 建立MFC AppWizard(exe )工程
图4-2 建立基于对话框的应用程序
将对话框资源中的默认对话框利用工具箱改造成如下界面,如图4-3所示。
图4-3显示员工信息程序界面设计
图4-3所示的界面中包含了5个Group Box,7个Static Text控件,5个Button 控件,和15个Edit Box控件,控件的基本信息列表如下表1所示。
表1 控件基本信息
5.1.2 MFC程序代码设计
为了能够将对话框界面上的控件能够与代码联系起来,需要为15个Edit Box控件建立Member Variables ,按Ctrl+w键进入MFC ClassWizard 界面,选择Member Variables选项卡,可显示成员变量设置界面,如图4-4和4-5所示。
图4-4成员变量设置界面1
图4-5成员变量设置界面2
通过该界面设置与15个Edit Box控件对应的成员变量,具体Type 与Member 请详见图4-4和4-5
MFC 编写代码也是非常重要的阶段,可以借鉴在设计基于DOS 界面的控制台应用程序的代码,并将其作必要的改写,具体改写如下。
①各员工的姓名直接在MFC 界面的姓名档中输入,等级和月薪直接赋值即可。
②修改内容包括:
● 将显示员工信息的prinft( ) 函数去掉,因为在图形界面的程序上已经不
需要连个函数承担输出功能了;
● 将存盘函数save( ) 去掉直接在MFC 界面的存盘档位每类员工建立文件
夹并保存,仍然使用文件输出流;
● 菜单函数也不再需要,直接通过对按钮的选择进行输入输出和存盘操
作。 具体代码如下:
①//为提交键编写的程序,用来实现信息的输出: void CLsqDlg::OnButton1( ) {
UpdateData(TRUE);
if(m_Mansger) //为经理的等级和月薪赋值 {
m_level1=4;
}
if(m_Salemansger) //为销售经理的等级和月薪赋值 {
m_level2=3;
}
if(m_Technology) //为兼职技术人员的等级和月薪赋值 {
m_level3=3;
}
if(m_Saleman) //为兼职推销员的等级和月薪赋值 {
m_wages3=m_time*100;
m_wages2=5000+m_sum2*0.005;
m_wages1=8000;
m_level4=1; }
②//为经理建立文件夹,将其信息保存在磁盘中 void CLsqDlg::OnButton2() {
ofstream fs("f:\\MFCMansger.txt");
fs
}
③//为销售经理建立文件夹,将其信息保存在磁盘中 void CLsqDlg::OnButton3() {
ofstream fs("f:\\MFCSalemansger.txt");
fs
}
④//为兼职技术人员建立文件夹,将其信息保存在磁盘中 void CLsqDlg::OnButton4()
{ ofstream fs("f:\\MFCTechnology.txt");
fs
}
⑤为兼职推销员建立文件夹,将其信息保存在磁盘中 void CLsqDlg::OnButton5()
{ ofstream fs("f:\\MFCSaleman.txt"); }
m_wages4=m_sum1*0.04;
UpdateData(FALSE);
fs
}
5.2基于MFC 的应用程序测试
运行程序后,首先出现的界面如图5-1所示。
图5-1程序初始运行界面
输入各类人员的姓名以及销售总额、工作时间、销售额后点提交按钮,具体结果如图5-2所示。
图5-2 显示全部信息的界面
分别点存盘栏中的四个按钮,便可从相应磁盘中得到各类人员的基本信息,如图6-1所示的MFCmansger.txt 、MFCsalemansger.txt 、MFCsaleman.txt 、MFCthecnology.txt :
图6-1为每类员工建立的文件夹
分别打开各个文件夹,便显示了员工的基本信息。如图6-2至6-5所示:
图6-2为经理建立的文件
图6-3为销售经理建立的文件
图6-4为兼职技术人员建立的文件
图6-5为兼职推销员建立的文件
结 论
整个程序中采用的是虚基类及其派生类的一系列成员函数的调用。由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基类继承来的成员全部可以访问,而对于建立派生类对象的外部模块来讲,基类的保护成员是无法访问的。通过保护访问类型和公有的继承方式,实现了基类Employee 的数据的有效共享和可靠保护。友元类函数通过访问基类及其派生类中的数据成员和成员函数实现了员工基本信息的输出和保存。同时建立结构体,开辟单链表为一维数组和动态内存分配方式。主函数采用菜单函数的形式实现了对员工基本信息的输入、全部信息的打印和保存。最后通过友元类的析构函数释放空间
MFC 程序与DOS 界面程序编写的最大不同是程序员需要将编程精力放在图形界面设计、图形界面输入输出以及界面元素和代码对应转换等问题上。
本次课程设基本实现了对小型人员信息的管理,可以说是取得了成功,然而好的程序绝不仅仅是只有功能性这一个指标,本此编写的MFC 程序虽然能实现所需功能,但从面向对象程序设计理念和图形界面设计要求来说,尚存在不足,主要包括以下几个方面。
(1)在DOS 界面程序中利用全局变量实现了编号的递增,但是在MFC 中,编号的递增没有得到圆满的解决方式。作为一个MFC 初学者,虽然能基本实现课设程序的要求,但是存在的缺陷我一定会在今后的学习中努力改正。
(2)在本次程序的MFC 页面中,鉴于要为四类员工建立各自的文件夹,以便保存基本信息,存盘按钮设置了4个,希望能在以后学习中努力改进,争取在一个存盘按钮中实现所有的保存。
参考文献
[1] 徐士良. C常用算法程序集. 北京:清华大学出版社,1995 [2] 钱能. C++程序设计教程(第二版). 北京:清华大学出版社,2007 [3] 谭浩强.C++面向对象程序设计(第三版). 北京:清华大学出版社,2005 [4] 李庆扬, 王能超, 易大义. 数值分析. 湖北:华中理工大学出版社,1986 [5] 陈志泊, 王春玲. 面向对象的程序设计语言—C++. 北京:人民邮电出版社,2002