一、課程設計目的
l
通過設計、實現媒體庫管理系統,熟悉面向對象的設計思想;
l
進一步熟悉、掌握STL中有關類型及其使用方法,泛型編程的風格。
二、系統設計要求
在這個課程設計中,你需要設計並實現一個繼承體系以管理圖書館中流通的物品:圖書、視頻光碟以及圖畫。你需要設計一個名為 Medium 的基類以表示所有流通物品所公有的屬性。接著,你需要從 Medium 類派生出 Book, Video, Painting 三個派生類。這個課程設計的目的是實現一個具有多態行為的設計。
三、系統功能模組圖
其中,Medium、Book、Painting、Video三个类均为题中所要求,而Search**则是为了搜索的方便而创建的它们将各自的基类中的可搜索的数值范围设置上限和下限。这样,只要重载运算符==,就可以轻松的使用库函数find来进行对目标对象的查找。
四、程序实现思路
4.1对数据结构的选择
基类Medium,有两个不同的和Display相关的成员函数,一个是可以指定ostream,另一个是专门用于输出到Console的,有一系列与输入相关的成员函数:InputTitle、InputAuthor、InputGrade……,也有一系列返回成员数据值的函数:Title、Author、Grade……,此外还有一系列支持多态的输入和返回成员数据值的成员函数,声明为virtual,但由于不知在哪里要生成实例的缘故,所以不能声明为纯虚函数。
而继承类Book、Painting、Video基本上与基类类似。此外,还有专门为搜索而声明的SearchBook、SearchPainting、SearchVideo类,它们在各自超类的基础上,增加了,搜索范围和与之相关的函数。
4.2.对功能的实现
其中,Medium、Book、Painting、Video四个类均为题中所要求,而Search**则是为了搜索的方便而创建的它们将各自的基类中的可搜索的数值范围设置上限和下限。
新增物品:只要使用相关的输入成员函数,即可轻松解决。
刪除物品:首先要对物品进行搜索,搜索将在一下搜索的部分讲解。将搜索的物品都存入一个Vector中,可以根据用户需要对其进行排序。排序实现当然是使用sort了,关于Compare的书写比较麻烦,就是要根据用户的输入,找到相应的成员数据,再根据不同的数据类型进行比较。显示的话,就调用专门输出到Console的成员函数。
顯示滿足搜索條件的物品:首先要输入物品的属性,为了使用库函数find,重载了运算符==,这使得查找极其方便,只要你愿意甚至可以输入物品的所有属性,只需循环多几次即可。在重载运算符==上就要花一些功夫了,首先要定义一系列的虚函数取出各自的属性值,对于范围的搜索还要对专门为搜索而诞生的类进行处理。
退出:當選擇“退出”時,会提示用户输入要保存数据的目标path,这时只需要调用Display成员函数,将输入参数的ostream设置好即可。
輸入說明:在程序一開始提示用戶輸入數據文件的名字。这将调用AddANewItem成员函数,它将构造相应对象,并将它们push_back进list即可。
4.3重载运算符==
由于涉及到较多的属性,只能用if-else if-else语句进行逐一判断。这也涉及到众多的虚函数,这将在關鍵程序代碼列出。首先要判断目标对象的该属性是否设置,如设置才进一步判断是否和比较对象相等或者目标对象的范围包括比较对象。
4.4句柄类
为了支持多态性,并减低使用类时的难度,从书上抄了个句柄类的模板,当然要正确使用它也是要花一定功夫的,在遇到一系列问题,并比较书上的使用例程,总算较好的达到了使用要求。
4.5画框类
为了界面的美观,还从书上抄了个画图的类,轻松地给字符串加上了框。
五、设计说明文档
该系统利用菜单对所需功能进行选择,在程序一開始提示用戶輸入數據文件的名字,具有较良好的操作性。
选择功能1,新增一個物品。按Book、Painting、Video三个不同类型增加。除標題外其餘信息都有默認值。
选择功能2,刪除物品。刪除物品前,先要输入搜索条件。搜索的过程与第三个功能相同,稍后介绍,搜索后可以选择相应的序号(如果存在一个或一个以上的结果,序号从1开始,否则提示没有此结果)进行删除,此操作不可恢复。也可以输入0,不进行删除操作。
选择功能3,顯示滿足搜索條件的物品。输入搜索条件时,先要指定一類物品(Book,Video,Painting),至多涉及該類別物品的兩個屬性,對于年份(出版年份、出品年份),書籍頁數,視頻時長和作品長度、寬度可以進行範圍查詢。搜索结果将在控制台按用户所需的顺序显示,当每超过五个(大概显示满一屏幕时),会提示用户是否继续显示。
选择功能4,退出本系统。退出时,需指定将数据存往文件的地址,这将会把所有的数据都保存到指定的文件。
六、课程设计心得
这次课程设计,主要了解了继承和多态的特性。对重载运算符后,只需要用find的库函数就能解决搜索问题还是比较满意的。这次在linux操作系统下,用diff和空的文件名比较,粗略估计代码有1.7K行(除了句柄类模板和画图类之外都是自己写的),对自己写的代码感觉还ok。对于菜单这种系统有了比较好的熟悉程度,为以后写类似的控制菜单打下了一定的基础。
在界面方面,个人还是较为满意的,其中有提示用户输入的语句,并且有类似Linux命令行下用户命令输入提示“……$”这种符号,对于大量数据输出,做到了超过一页时提示用户是否要继续显示(—more—)。
这次的类设计的还不错,引进了专门为实现搜索的类。
七、关键程序代码
bool Library_item::operator ==(const Library_item &rhv)
{
bool
flag = true;
if
(rhv.cp->type != this->cp->type)
flag = false;
else
if (!(rhv.cp->Title().empty() || this->cp->Title() == rhv.cp->Title()))
flag = false;
else
if (!(rhv.cp->Author().empty() || this->cp->Author() == rhv.cp->Author()))
flag = false;
.
. 省略大量的虚函数调用,与上面类似。
.
return
flag;
}
bool MediaLib::Compare(Library_item first, Library_item second)
{
typedef
string::const_iterator Sit;
for(Sit
iter = howToDisplayResult.begin(); iter != howToDisplayResult.end(); ++iter) { //如: “1< 2>”
if
(*iter == ' ') continue; //跳过空格
if
(*iter >= '1' && *iter <= '9') { //数字
int
tmpNum = *iter - '0';
do
{ ++iter; }while (*iter == ' '); //跳过空格
if
(*iter != '<' && *iter != '>') --iter; //只有数字和<、>
string tmpType =
first->DataMember(tmpNum, "type");//返回比较类型
//以下为比较部分!
if
(tmpType == "string") { //类型为string的比较
string firstString,
secondString;
firstString =
first->DataMember(tmpNum, "data");
secondString =
second->DataMember(tmpNum, "data");
if (firstString == secondString ) continue;
else {
if (*iter == '>') return
firstString > secondString;
else return firstString < secondString;
}
}
此处省略unsigned int类型。。。
}
}
return
false;
}
文章评论(0条评论)
登录后参与讨论