资源描述
单击此处编辑母版标题样式,编辑母版文本样式,第二级,第三级,第四级,第五级,2021/4/7,#,11.1.1,功能描述,本章将实现一个简单的酒店管理系统,系统具有三大功能模块,用以实现酒店客房的显示、添加、删除、状态设置等操作,。,11.1.1 功能描述本章将实现一个简单的酒店管理系统,系统,11.1.1,功能描述,11.1.1 功能描述,11.1.1,功能描述,酒店管理系统各个模块的主要功能:,(,1,)客房模块,:客房模块主要功能包括获取客房数据,如客房编号、名称、价格、面积、床位数量、状态(空闲或入住)等,将客房数据保存到外部文件,在显示客房信息时从文件中读取客房数据。,11.1.1 功能描述酒店管理系统各个模块的主要功能:,11.1.1,功能描述,(,2,)客房管理模块,:客房管理模块主要用于管理客房。例如,添加客房、删除客房、查找客房、设置客房状态等。,(,3,)界面模块,:界面模块主要用于显示酒店管理系统的界面,例如,显示操作菜单,为添加客房、删除客房、设置客房状态、显示客房信息等操作提供提示信息。,11.1.1 功能描述(2)客房管理模块:客房管理模块主要用,11.1.2,项目设计,1,.,客房模块,客房管理模块主要负责保存、读取客房数据,如客房编号、名称、价格等,该模块需要设计一个客房类,GuestRoom,,类中定义客房的数据信息作为成员变量,并提供获取这些客房数据的成员函数。此外,由于,GuestRoom,类中还要负责将客房数据保存到本地文件中,在显示客房信息时,负责从文件读取客房信息,因此还需要定义文件读写函数。,11.1.2 项目设计1.客房模块,11.1.2,项目设计,11.1.2 项目设计,11.1.2,项目设计,2,.,客房管理模块,客房管理模块主要负责管理客房,如查看客房状态、添加客房、删除客房、设置客房状态等,该模块需要设计一个客房管理类,GuestRoomManager,,定义各种功能函数。由于管理客房时,每次需要从文件中读取客房数据,在设计时,可以将读取的客房数据保存到一个,map,容器中,以客房编号为键,以,GuestRoom,类对象为值,因此,,GuestRoomManager,类中需要定义一个,map,容器作为成员变量存储客房信息。,11.1.2 项目设计2.客房管理模块,11.1.2,项目设计,11.1.2 项目设计,11.1.2,项目设计,3,.,界面模块,界面模块主要负责显示酒店管理系统的操作界面,为添加客房、删除客房、设置客房状态、显示客房信息等操作提供提示信息,该模块需要设计一个界面类,RoomView,类,定义功能函数为各种操作提供界面显示。,11.1.2 项目设计3.界面模块,11.1.2,项目设计,三个类之间的关系,11.1.2 项目设计三个类之间的关系,11.2.1,客房模块的实现,客户模块,负责保存、读取客房数据,如客房编号、名称、价格等,,该模块需要实现,11,个函数:,(,1,),GuestRoom(),:,GuestRoom,类的构造函数,初始化类成员变量。,(,2,),generate_number(),:,用于生成客房编号。,(,3,),show_state(),:,用于显示客房状态,。,(,4,),sava_data(),:,用于将客房数据保存到外部文件中,。,(,5,),read_data(),:,从文件中读取客房数据,并存储到,map,容器中,将,map,容器返回。,11.2.1 客房模块的实现客户模块负责保存、读取客房数据,,11.2.1,客房模块的实现,(,6,),get_num(),:,用于获取客房编号。,(,7,),set_state(),:,用于设置客房状态。,(,8,),get_name(),:,用于获取客房名称。,(,9,),get_price(),:,用于获取客房价格。,(,10,),get_area(),:,用于获取客房面积。,(,11,),get_bed_num(),:,用于获取客房的床位数量。,11.2.1 客房模块的实现(6)get_num():用于获,11.2.2,客房管理模块的实现,客房管理模块用于管理客房,,该模块需要实现,5,个函数:,(,1,),GuestRoomManager(),:,类的构造函,数,,通过,GuestRoom,类的匿名对象调用,read_data(),函数读取文件,即每次通过,GuestRoomManager,类对象管理客房时,都会先读取文件获取客房数据。,(,2,),check_in(),:,用于查找客房,其参数为客房编号,。,(,3,),add_room(),:,用于添加客房,其参数为,GuestRoom,类对象,即要添加的客房。,11.2.2 客房管理模块的实现客房管理模块用于管理客房,该,11.2.2,客房管理模块的实现,(,4,),remove_data(),:,用于删除客房数据,其参数为要删除客房的编号。,(,5,),set_room_state(),:,用于设置客房状态,其参数为客房编号。,11.2.2 客房管理模块的实现(4)remove_data,11.2.2,界面模块的实现,界面模块负责显示酒店管理系统的操作界面,为添加客房、删除客房、设置客房状态、显示客房信息等操作提供提示信息,。该模块实现,6,个函数。,(,1,),show_menu(),:,用于显示酒店管理系统菜单,。,(,2,),add_room(),:,用于添加客房。,(,3,),remove_data(),:,用于删除客房。,(,4,),set_room(),:,用于设置客房状态。,(,5,),show_all(),:,用于显示所有客房信息。,(,6,),run(),:,用于启动酒店管理系统。,11.2.2 界面模块的实现界面模块负责显示酒店管理系统的操,11.2.2,界面模块的实现,前面已经完成了酒店管理系统中所有功能模块的编写,但是功能模块是无法独立运行的,需要一个程序去将这些功能模块按照项目的逻辑思路整合起来,这样才能完成一个完整的项目。此时就需要创建一个,main.cpp,文件来整合这些代码,,main.cpp,文件中包含,main(),函数,是程序的入口。,main(),函数,11.2.2 界面模块的实现前面已经完成了酒店管理系统中所有,11.3,效果显示,1,.,系统主菜单,系统运行后,显示系统主菜单,。,11.3 效果显示1.系统主菜单,11.3,效果显示,2,.,显示客房信息,输入数字,1,,显示客房信息,第一次运行程序时,由于还没有客房,因此显示客房信息时,没有任何信息,系统会提示先添加客房,。,11.3 效果显示2.显示客房信息,11.3,效果显示,3,.,添加客房信息,输入数字,4,,添加客房信息,。,11.3 效果显示3.添加客房信息,11.3,效果显示,4,.,显示客房信息,添加客房之后,再次输入数字,1,,显示客房信息,。,11.3 效果显示4.显示客房信息,11.3,效果显示,5,.,设置客房状态,输入数字,2,可以设置客房状态,在设置客房状态时,需要输入客房编号,。,11.3 效果显示5.设置客房状态,11.3,效果显示,输入客房编号之后,系统会更改该编号的客房状态。回到主菜单再次输入数字,1,,显示客房信息,可以看到客房状态改变,。,11.3 效果显示输入客房编号之后,系统会更改该编号的客房状,11.3,效果显示,6,.,删除客房状态,输入数字,3,,可以删除客房信息。在删除客房信息时,输入客房编号,。,11.3 效果显示6.删除客房状态,11.3,效果显示,输入客房编号后,按回车键回到主菜单,系统会删除对应编号的客房信息。此时,再次输入数字,1,查看客房信息,编号为,84717,的客房不存在,。,11.3 效果显示输入客房编号后,按回车键回到主菜单,系统会,11.3,效果显示,7,.,退出管理系统,输入数字,5,,可以退出酒店管理系统,。,11.3 效果显示7.退出管理系统,11.4,程序调试,在,程序开发过程中难免会出现各种各样的错误。为了快速发现和解决程序中的这些错误,可以使用,Visual Studio2019,自带的调试功能,通过程序调试快速定位错误。,11.4 程序调试在程序开发过程中难免会出现各种各样的错误。,11.4.1,设置断点,1,.,单击,鼠标右键,在程序中,将鼠标放置在要插入断点的行,单击鼠标右键,【断点】,【插入断点】,。,11.4.1 设置断点1.单击鼠标右键,11.4.1,设置断点,在上图中,,单击,插入断点选项后,选中的代码行左边会有一,个,红,色,的,圆点,。,11.4.1 设置断点在上图中,单击插入断点选项后,选中的代,11.4.1,设置断点,调试,完毕要删除断点也是非常简单的,将鼠标放置在断点代码行,单击鼠标右键,【删除断点】,。,11.4.1 设置断点调试完毕要删除断点也是非常简单的,将鼠,11.4.1,设置断点,2,.,单击,鼠标左键,除了上述方式,读者还可以在代码左边的灰色区域单击鼠标左键插入断点,断点插入成功后左侧会也有彩色圆点出现。同样,删除断点时,只需再次左键单击代码左侧已插入的彩色圆点,便可删除断点。相比于上一种断点插入方式,这种方式更简单便捷。,11.4.1 设置断点2.单击鼠标左键,11.4.2,单步调试,当,程序出现,Bug,时,为了找出错误的原因,通常会采用一步一步跟踪程序执行流程的方式,这种调试方式称为单步调试。单步调试分为逐语句(快捷键【,F11,】)和逐过程(快捷键【,F10,】),逐语句调试会进入方法内部调试,单步执行方法体的每条语句,逐过程调试不会进入方法体内部,而是把方法当作一步来执行。,11.4.2 单步调试当程序出现Bug时,为了找出错误的原因,11.4.2,单步调试,1,.,逐,语句调试,设置,断点之后,单击工具栏中的运行,按钮,,程序运行之后,遇到断点就会停止,执行,。,11.4.2 单步调试1.逐语句调试,11.4.2,单步调试,调试,启动后,当遇到断点时,程序会停止执行,等待用户进行操作。程序开始调试时,,Visual,Studio 2019,工具栏按钮会发生变化,11.4.2 单步调试调试启动后,当遇到断点时,程序会停止执,11.4.2,单步调试,继续,执行:该按钮可以跳过调试语句,继续执行程序。,停止,调试:该按钮用于停止调试程序,快捷键,Shift+F5,。,重新,启动:该按钮用于重新启动程序调试,快捷键,Ctrl+Shift+F5,。,显示,下一条语句:该按钮用于显示下一条执行的语句,快捷键,Alt+,数字键,*,。,逐,语句:该按钮可以让程序按照逐语句进行调试,快捷键,F11,。,逐,过程:该按钮可以让程序按照逐过程进行调试,快捷键,F10,。,跳出,:该按钮用于跳出正在执行的程序,快捷键,Shift+F11,。,11.4.2 单步调试 继续执行:该按钮可以跳过调试语句,11.4.2,单步调试,如果在调试时想逐语句调试,则按快捷键【,F11,】或单击工具栏中的逐语句调试按钮,程序会进入,run(),函数内部一条一条执行语句。,11.4.2 单步调试如果在调试时想逐语句调试,则按快捷键【,11.4.2,单步调试,在,上图,中,继续按快捷键【,F11,】或单击工具栏中的逐语句调试按钮,程序就会逐条语句往下执行,当执行,完,run(),函数就会接着,进入,show_menue(),函数执行。,11.4.2 单步调试在上图中继续按快捷键【F11】或单击工,11.4.2,单步调试,2,.,逐,过程调试,逐过程调试在每次调试时执行一个函数,当调试开始时,按快捷键【,F10,】或单击工具栏中的逐过程调试按钮,可以一次执行一个函数。连续按快捷键【,F10,】或单击工具栏中的逐过程调试按钮,程序会逐个函数的往下执行,直到程序执行完毕,。,11.4.2 单步调试2.逐过程调试,11.4.2,单步调试,调试,程序一般是为了查找错误,当查找完错误之后就会结束调试,并不会全程调试。如果查找完错误之前,想要结束调试,可单击工具栏中的运行按钮继续往下执行程序,也可以单击工具栏中的停止调试按钮结束程序执行。,11.4.2 单步调试调试程序一般是为了查找错误,当查找完错,11.4.3,观察变量,1,.,鼠标悬停法,Visual Studio2019,可以通过鼠标悬停的方式查看变量的值,即鼠标指向变量,变量就会显示出其值。例如,,run(),函数中定义了变量,flag,,下面以查看变量,flag,的值为例演示,Visual Studio2019,查看变量的方法。程序还未执行第,82,行代码:,cinflag,,此时,变量,flag,的值为,-1,,可通过鼠标悬停的方式进行查看,将鼠标悬停在变量,flag,上面,,Visual Studio2019,会显示出,flag,的值,,11.4.3 观察变量1.鼠标悬停法,11.4.3,观察变量,11.4.3 观察变量,11.4.3,观察变量,通过鼠标悬停的方式查看到变量,flag,的值为,-1,。继续逐语句往下执行,当执行完第,82,行代码时,通过键盘输入,flag,的值,此时再查看,flag,的值,,flag,就变成了输入的数值,。,11.4.3 观察变量通过鼠标悬停的方式查看到变量flag的,11.4.3,观察变量,2,.,使用局部变量窗口查看变量的值,除了鼠标悬停之外,还可以通过,Visual Studio2019,下面的局部变量窗口查看变量的值,在菜单栏中选择【调试】,【窗口】,【局部变量】打开局部变量窗口查看变量的值,在该窗口中可以看到当前运行代码之前所有变量的名称、当前值和类型,。,11.4.3 观察变量2.使用局部变量窗口查看变量的值,11.4.3,观察变量,3,.,使用快速监视窗口查看变量的值,程序调试过程中,在代码区单击鼠标右键选择【快速监视】,弹出快速监视窗口,在该窗口的表达式文本框中输入要监视的变量,单击【重新计算】按钮,就可以查看变量的名称、值与数据类型,。,11.4.3 观察变量3.使用快速监视窗口查看变量的值,11.4.3,观察变量,4,.,使用即时窗口查看变量的值,在代码调试的过程中,在菜单栏选择【调试】,【窗口】,【即时】打开即时窗口,在即时窗口中直接输入程序中的变量名,按回车即可查看变量的值,也可以在变量名前加上“,&,”(取地址符),查看变量的地址,。,11.4.3 观察变量4.使用即时窗口查看变量的值,11.4.4,项目调试,在酒店管理系统的主菜单中,要求输入,15,之间的整数,如果输入不符合要求的数据,如输入一个字符,则系统会一直闪屏无响应。对此进行分析,主菜单的输入操作由界面模块的,run(),函数实现,在,room_view.cpp,文件中,第,81105,行代码定义,int,类型变量,flag,,利用,cin,对象从键盘输入,flag,的值,然后判断,flag,的值,根据,flag,的值调用不同的函数以实现不同的操作。,11.4.4 项目调试在酒店管理系统的主菜单中,要求输入1,11.4.4,项目调试,当输入字符时,系统闪屏无响应,表明第,81105,行代码在输入,flag,值或,switch,case,语句对,flag,的处理不够严谨,需要对第,81105,行代码进行调试。,在,room_view.cpp,文件中第,81,行代码设置断点,。,11.4.4 项目调试当输入字符时,系统闪屏无响应,表明第8,11.4.4,项目调试,11.4.4 项目调试,11.4.4,项目调试,设置断点之后开始调试,通过逐语句调试跟踪每一步操作。当程序运行至第,83,行代码时,发现在调用,cin,对象输入,flag,的值时,没有对,cin,对象作错误处理。利用,cin,对象为,int,类型变量输入数据时,如果输入的是,char,类型的数据,则,cin,对象的一个错误标记会被设置,,cin,对象就不能再使用,再次调用,cinflag,会直接返回,false,(即,0,)。,switch,case,语句无法匹配到,0,,因此,,while(state),循环会无限循环,导致系统主菜单界面闪屏无响应。,11.4.4 项目调试设置断点之后开始调试,通过逐语句调试跟,11.4.4,项目调试,经过上面的调试和分析,已确定了程序中的,bug,所在,在修改时,可以调用,clear(),函数清除,cin,对象的错误标志,恢复,cin,对象的默认状态;然后再调用,ignore(),函数将,cin,对象中不符合输入选项的数据忽略。在图,11-26,中第,83,行代码后添加如下代码,解决由于输入错误导致程序运行出错的问题。,cin.clear();/,清除,cin,对象的错误标志,cin.ignore();/,忽略,cin,对象中残留数据,11.4.4 项目调试经过上面的调试和分析,已确定了程序中的,11.5,项目心得,1,.,项目整体规划,每一个项目,在实现之前都要进行分析设计,项目整体要实现哪些功能。将这些功能划分成不同的模块,如果模块较大还可以在内部划分成更小的功能模块。这样逐个实现每个模块,条理清晰。在实现各个模块后,需要将模块整合,使各个功能协调有序的进行。,11.5 项目心得1.项目整体规划,11.5,项目心得,2,.,类的设计,在项目开发中,类的设计要简洁、独立,要降低类之间的耦合性。在本项目中,每个模块设计了一个类,每个类都根据模块的功能封装了成员变量与成员函数。,GuestRoom,类负责保存客房数据,,GuestRoomManager,类用于管理客房数据,,GuestView,类用于显示系统界面,三个类相互独立,若需要增加新的功能只需要修改,GuestRoomManager,即可,上层显示模块,GuestView,只需要调用即可。,11.5 项目心得2.类的设计,11.5,项目心得,在设计时,,GuestRoom,类将客房数据保存到文件或者从文件中读取数据时,以,map,容器作为载体,实现客房数据的存储和读取,如,GuestRoomManager,类中以,map,容器作为成员变量,实现对客房数据的管理;,GuestView,类以,GuestRoomManager,类对象作为成员变量,以实现各个操作的界面管理,三个类又相互联系。,11.5 项目心得在设计时,GuestRoom类将客房数据保,11.5,项目心得,3,.,清屏,酒店管理系统是一个多操作项目,每一次操作切换需要把上一个操作的内容清空,这就要涉及清屏,如果不清屏,会造成多个屏幕内容显示过多。清屏可使用,system(cls),语句实现,本项目就在多处使用该语句,场景切换处理的很好。,11.5 项目心得3.清屏,11.6,本章小结,本章综合运用前面所讲的知识,设计了一个综合项目酒店管理系统,使大家了解如何开发一个多模块多文件的,C+,程序。在开发这个程序时,首先将一个项目拆分成若干个小的模块,然后分别设计每个模块所需要的类。在实现时,将每个模块的声明和定义分开,放置在头文件和源文件中,最后在一个含有,main(),函数的源文件中,将它们的头文件包含进来,并利用,main(),函数将所有的模块联系起来。通过这个项目的学习,读者会对,C+,程序开发流程有个整体的认识,这对实际工作中是大有裨益的。,11.6 本章小结本章综合运用前面所讲的知识,设计了一个综合,
展开阅读全文