邮局书籍管理系统实训报告.docx
《邮局书籍管理系统实训报告.docx》由会员分享,可在线阅读,更多相关《邮局书籍管理系统实训报告.docx(17页珍藏版)》请在冰豆网上搜索。
![邮局书籍管理系统实训报告.docx](https://file1.bdocx.com/fileroot1/2023-6/8/abe014c8-0506-4024-abce-8967a61c7cad/abe014c8-0506-4024-abce-8967a61c7cad1.gif)
邮局书籍管理系统实训报告
实训报告
一、概要
用C++面向对象程序设计的相关知识设计并实现一个邮局的书籍信息管理系统。
该系统可用于书籍份数、作者、邮费等信息的查询。
二、系统需求分析
(1)用户需求分析
图1用户需求分析
用户进入系统可以选择相应物品的信息(书籍信息、期刊信息、文化品信息),当选择后会直接显示该物品的详细信息(作者信息、份数信息、邮费信息、出版社信息)。
(2)功能分析
程序主要实现3个功能:
查询书籍信息的功能、查询期刊信息的功能、查询文化品信息的功能。
书籍信息功能中包括:
书名、出版社、作者、书编号、邮寄书的数量、邮寄书的费用。
期刊信息功能包括:
期刊名、期刊月份、邮寄书的数量、邮寄书的费用。
文化品信息功能包括:
书名、出版社、作者、书编号、邮寄书的数量、邮寄书的费用、期刊名、期刊月份、邮寄书的数量、邮寄书的费用、所寄邮件的总份数、所需总费用。
三、系统设计与实现
(1)系统开发环境
操作系统:
window7
开发平台:
C-Free5.0
(2)系统总体设计
图2邮局管理系统概况
Main函数中do···while、switch结构实现界面的循环。
函数a()处理书籍信息、函数b()处理期刊信息、函数c()处理文化品信息。
设置一个邮局的基类Post,该类中有计算所寄印刷品prin的份数numb和计算所寄印刷品的邮寄费cost。
设置一个书籍派生类Book,该类中有书名titl和press,该类通过邮局寄出书籍3本,输出邮寄费cost;同时再设置一个作者派生类Auth,该类中有姓名name和书号isbn,该类作为书籍派生类辅助类。
设置一个期刊派生类Jour,该类中有期刊名称jou_na和期刊月份jou_mon,该类通过邮局寄出期刊5本,输出邮寄费cost。
设置一个文化品派生类Cul_pro,该类中要邮寄三本书和两本期刊,在邮寄时要寄出单位Sen_un。
四、功能设计
(1)基类Post、书籍派生类Book、作者派生类Auth、期刊派生类Jour和文化品派生类Cul_pro的设计。
如图3
图3类图设计
此类图的设计运用了C++中提供的虚基类方法,使得在继承间接共同基类时保留一份成员。
以下是关于C++中虚基类的学习与认识:
假设类D是类B和类C公用派生类,而类B和类C又是类A的派生类,如图11.21所示。
设类A有数据成员data和成员函数fun;派生类B和C分别从类A继承了data和fun,此外类B还增加了自己的数据成员data_b,类C增加了数据成员data_c。
如果不用虚基类,就会在类D中保留了类A成员data的两份拷贝,分别表示为intB:
:
data和intC:
:
data。
同样有两个同名的成员函数,表示为voidB:
:
fun()和voidC:
:
fun()。
类B中增加的成员data_b和类C中增加的成员dat_c不同名,不必用类名限定。
此外,类D还增加了自己的数据成员data_d和成员函数fun_d。
现在,将类A声明为虚基类,方法如下:
classA//声明基类A
{
//代码
};
classB:
virtualpublicA//声明类B是类A的公用派生类,A是B的虚基类
{
//代码
};
classC:
virtualpublicA//声明类C是类A的公用派生类,A是C的虚基类
{
//代码
};
注意:
虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。
因为一个基类可以在生成一个派生类时作为虚基类,而在生成另一个派生类时不作为虚基类。
声明虚基类的一般形式为:
class派生类名:
virtual继承方式 基类名
即在声明派生类时,将关键字virtual加到相应的继承方式前面,经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次,也就是说,基类成员只保留一次。
需要注意:
为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。
否则仍然会出现对基类的多次继承。
如果在派生类B和C中将类A声明为虚基类,而在派生类D中没有将类A声明为虚基类,则在派生类E中,虽然从类B和C路径派生的部分只保留一份基类成员,但从类D路径派生的部分还保留一份基类成员。
虚基类的初始化
如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接派生或间接派生的派生类)中,通过构造函数的初始化表对虚基类进行初始化。
例如
classA//定义基类A
{
A(inti){}//基类构造函数,有一个参数};
classB:
virtualpublicA//A作为B的虚基类
{
B(intn):
A(n){}//B类构造函数,在初始化表中对虚基类初始化
};
classC:
virtualpublicA//A作为C的虚基类
{
C(intn):
A(n){}//C类构造函数,在初始化表中对虚基类初始化
};
classD:
publicB,publicC//类D的构造函数,在初始化表中对所有基类初始化
{
D(intn):
A(n),B(n),C(n){}
};
注意:
在定义类D的构造函数时,与以往使用的方法有所不同。
以往,在派生类的构造函数中只需负责对其直接基类初始化,再由其直接基类负责对间接基类初始化。
现在,由于虚基类在派生类中只有一份数据成员,所以这份数据成员的初始化必须由派生类直接给出。
如果不由最后的派生类直接对虚基类初始化,而由虚基类的直接派生类(如类B和类C)对虚基类初始化,就有可能由于在类B和类C的构造函数中对虚基类给出不同的初始化参数而产生矛盾。
所以规定:
在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。
引用:
(2)函数功能。
函数原型1voida()
函数功能:
处理图书信息,输出书名、出版社、作者、书编号、邮寄书的数量、邮寄书的费用。
函数原型2voidb()
函数功能:
处理期刊信息,输出期刊名、期刊月份、邮寄书的数量、邮寄书的费用。
函数原型3voidc()
函数功能:
书名、出版社、作者、书编号、邮寄书的数量、邮寄书的费用、期刊名、期刊月份、邮寄书的数量、邮寄书的费用、所寄邮件的总份数、所需总费用。
(3)各类的参构造函数,静态变量。
Post类为系统默认的无参构造函数。
Post类的静态变量:
staticintb_count;
staticintn_count;
staticintb_price;
staticintn_price;
Auth类参构造函数:
Auth(stringa_n,intb_nu)
{
author_name=a_n;
book_number=b_nu;
}
Auth类的静态变量:
public:
stringauthor_name;
intbook_number;
Book类参构造函数:
Book(stringa_n,intb_nu,stringadr,stringb_na):
per(a_n,b_nu)
{
book_name=b_na;
adress=adr;
}
Book类的静态变量:
private:
stringbook_name;
stringadress;
public:
Authper;
Jour类构造函数:
Jour(stringpin,intmo):
piname(pin),moth(mo){}
Jour类的静态变量:
private:
stringpiname;
intmoth;
Cul_pro类构造函数:
Cul_pro(stringa_n,intb_nu,stringadr,stringb_na,stringpin,intmo,stringfr="湖北省黄冈市蕲春县"):
Book(a_n,b_nu,adr,b_na),Jour(pin,mo)
{
from=fr;
}
Cul_pro类静态变量:
private:
stringfrom;
(4)设计相应的成员函数、成员变量。
Book类成员函数:
intb_money(intb_c,intb_p),入口参数:
为数量和费用,出口函数为总的邮费returnn_count*n_price;
voiddisplay()输出,书名、出版社、作者名、书编号
Jour类成员函数:
voidshow()显示,期刊名、期刊月分
intn_money(intn_c,intn_p)入口参数:
为数量和费用,出口函数为总的邮费returnn_count*n_price;
Cul_pro类成员函数:
voidshow()显示,邮寄书数为、费用为,邮寄期刊数为、费用为,所邮寄邮件的总份数、所需总费用、邮寄者地址。
(5)在多重继承下实现虚函数描述。
Cul_pro类是Book类和Jour类公用派生类,而类Book和类Jour又是类Post的派生类,因此运用了虚拟基类。
如图3所示。
五、学习感悟
两天的实训课程,给我了很大的影响。
通过这次实训是我明白,学习一种编程语言不能只看书上还要不停的上机练习,才能体会出书中所讲的道理。
通过这次的实训我找到了我很多遗漏的知识点,还有很多以前不懂得问题。
在查询资料中更让自己获益匪浅。
想要理解一段代码,实现一个功能并不是一件简单的事情。
就像刚开始看到老师给的这些代码,总感觉没什么可写没什么可说,这只是一个极其简单的小程序而已,但是当开始一句一句的注释解释的时候才发现自己根本不会。
很多知识不知道,然后开始查资料,开始XX开始请教别人,这时才发现原来有如此多的知识点。
当然这次的实训给我最大的感受就是一定要学会怎样去查询资料,怎样遇到问题时查询资料并且解决。
互联网是一个很好的工具,可以查询到很多的问题。
所以实训带给我的第一点就是如何利用网络解决遇到的问题。
第二点就是多看书,书中的知识点都是最基本的最基础的知识,如果书中的这些知识点都看不懂的话那无论如何也编写不出程序的。
第三点就是要静下心来耐心的学习,切不可眼高手低,必须一点一滴的踏踏实实的学会每一个知识点。
只有真正掌握了一个知识点到用时才会得心应手,才会越学越轻松,必经这门知识就那么多掌握一个就上一个嘛。
当然更感谢老师教会了我这些,让我领悟到了这些!
六、附代码
#include
#include
#include
usingnamespacestd;
/*邮局基类Post*/
classPost
{
public:
staticintb_count;
staticintn_count;
staticintb_price;
staticintn_price;
};
classAuth/*作者派生类*/
{
public:
stringauthor_name;/*静态变量*/
intbook_number;
Auth(stringa_n,intb_nu)/*构造函数*/
{
author_name=a_n;
book_number=b_nu;
}
};
/*书籍派生类Book*/
classBook:
virtualpublicPost
{
private:
stringbook_name;/*静态变量*/
stringadress;
public:
Authper;
Book(stringa_n,intb_nu,stringadr,stringb_na):
per(a_n,b_nu)/*构造函数*/
{
book_name=b_na;
adress=adr;
}
intb_money(intb_c,intb_p)/*成员函数入口参数:
为数量和费用,出口函数为总的邮费returnn_count*n_price;*/
{
return(b_c*b_p);
}
voiddisplay()/*成员函数输出,书名、出版社、作者名、书编号*/
{
cout<<"书名:
"<"<"<"<}
};
/*期刊派生类Jour*/
classJour:
virtualpublicPost
{
private:
stringpiname;/*静态变量*/
intmoth;
public:
Jour(stringpin,intmo):
piname(pin),moth(mo){}/*构造函数*/
virtualvoidshow()/*成员函数显示,期刊名、期刊月分*/
{
cout<<"期刊名:
<<"<>"<"<}
intn_money(intn_c,intn_p)/*成员函数入口参数:
为数量和费用,出口函数为总的邮费returnn_count*n_price;*/
{
returnn_count*n_price;
}
};
/*文化品派生类Cul_pro*/
classCul_pro:
publicBook,publicJour
{
private:
stringfrom;
public:
Cul_pro(stringa_n,intb_nu,stringadr,stringb_na,stringpin,intmo,stringfr="湖北省黄冈市蕲春县"):
Book(a_n,b_nu,adr,b_na),Jour(pin,mo)
{/*构造函数*/
from=fr;
}
voidshow()/*成员函数显示,邮寄书数为、费用为,邮寄期刊数为、费用为,所邮寄邮件的总份数、所需总费用、邮寄者地址。
*/
{cout<<"邮寄书数为:
"<"<cout<<"邮寄期刊数为:
"<"<cout<<"所邮寄邮件的总份数:
"<<(b_count+n_count)<cout<<"所需总费用:
"<<(b_money(b_count,b_price)+n_money(n_count,n_price))<cout<<"邮寄者地址:
"<}
};
intPost:
:
b_count=0;
intPost:
:
b_price=2;
intPost:
:
n_count=0;
intPost:
:
n_price=1;
voida()
{Book*bp;/*Book类型的指针*/
/*Book类型的数组*/
Bookgushao[3]={
Book("王沛礼",19900709,"南理出版社","我的大学"),
Book("封少华",20121212,"机械出版社","我的梦"),
Book("顾少座",20160623,"清华大学出版社","我爱学习")
};
for(inti=0;i<3;i++)/*遍历全部书籍*/
{
printf("第%d本书的信息:
",i+1);
gushao[i].display();/*调用Book类里的display函数*/
cout.put(10);/*空行*/
Post:
:
b_count++;/*记录书籍数量*/
}
cout<<"邮寄书的数量为:
"<:
b_count<"<b_money(Post:
:
b_count,Post:
:
b_price)<cout<<"查询成功!
按enter返回主菜单";
cin.get();cin.get();
}
voidb()
{
Jourgu[3]={/*Jour类型的数组*/
Jour("好好学习",2),
Jour("天天向上",5),
Jour("她",0)
};
Jour*np;/*Jour类型的指针*/
for(inti=0;i<3;i++)
{
printf("第%d期刊的信息:
",i+1);
gu[i].show();cout.put(10);
Post:
:
n_count++;
}
cout<<"邮寄书的数量为:
"<:
n_count<"<n_money(Post:
:
b_count,Post:
:
b_price)<cout<<"查询成功!
按enter返回主菜单";
cin.get();cin.get();
}
voidc()
{Cul_progushaozuo[3]={
Cul_pro("我的大学",1,"南理出版社","封少华","好好学习",2),
Cul_pro("我的梦",2,"机械出版社","顾少座","天天向上",5),
Cul_pro("我爱学习",3,"清华大学出版社","冯春","她",0),
};
inti;
for(i=0;i<3;i++)
{
gushaozuo[i].display();
cout.put(10);
}
for(i=0;i<3;i++)
{
gushaozuo[i].Jour:
:
show();
cout.put(10);
}
Jour*np;
np=gushaozuo;
np->show();
cout<<"查询成功!
按enter返回主菜单";
cin.get();cin.get();
}
intmain()
{intj;
do
{
cout<<"\t\t\a\a\a\a邮件查询系统!
\a\a\a\n\n";
cout<<"********************************************************************************\n";
cout<<"*****图书类***********************************查询请按1************************"<cout<<"*****期刊类***********************************查询请按2************************"<cout<<"*****查询书和期刊类***************************查询请按3************************"<cout<<"*****退出查询*********************************返回请按4************************"<cout<<"\t\t\t****请选择操作==>>";
scanf("%d\a\a",&j);
switch(j)
{
case1:
a();break;
case2:
b();break;
case3:
c();break;
case4:
system("cls");cout<<"\t\t\n已退出程序!
\n";cin.get();cin.get();break;
default:
cout<<"\a\a\a\a\a\a输入错误!
\n\n计算机正发出警告\n\n请从新输入!
";break;
}
system("cls");
}while(j!
=4);
cout<<"\t\t\t\t谢谢!
";
cin.get();
cin.get();
}