西安石油大学大二上C++面向对象程序设计课件第5章程序.docx
- 文档编号:4419552
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:15
- 大小:25.21KB
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx
《西安石油大学大二上C++面向对象程序设计课件第5章程序.docx》由会员分享,可在线阅读,更多相关《西安石油大学大二上C++面向对象程序设计课件第5章程序.docx(15页珍藏版)》请在冰豆网上搜索。
西安石油大学大二上C++面向对象程序设计课件第5章程序
.1.1图书馆信息——公有继承举例
公有继承的特点是:
基类的保护成员和公有成员将成为派生类的保护成员和公有成员。
公有继承的应用意义是:
基类设计完成的代码资源可以为所有该基类的公有派生类共享。
公有继承是软件设计中最常用的派生类产生方式。
【例51.1】分析图书馆的图书和杂志信息关系,设计一个简单的图书和杂志借阅系统。
要求:
每个读者最多可借5本图书和10本杂志。
设计分析:
图书馆有两种类型的资料,一种是图书,一种是杂志。
图书和杂志有一些共同的地方,因此可以设计一个资料类作为它们的基类。
资料类的成员变量包括名字和条码。
图书类的成员变量除继承基类的名字(书名)和条码外,还包括作者和内部分类号。
杂志类的成员变量除继承基类的名字(杂志名)和条码外,还包括卷号。
读者要借阅图书或杂志,就要设计一个读者类。
读者类的成员变量包括读者姓名、借书证号。
由于每个读者最多可借5本图书和10本杂志,所以,要分别设计一个所借图书线性表和所借杂志线性表。
每个线性表分别包括一个保存图书或杂志的数组成员变量,和一个记录已借图书或已借杂志数目的成员变量。
资料类及其派生类设计如下:
//Retrieval.h
#include
classRetrieval//资料类
{
protected:
charTitle[40];//名字
longCode;//条码
public:
Retrieval();
Retrieval(char*title,longcode);
longGetCode(){returnCode;}
voidShow();//显示资料信息
};
Retrieval:
:
Retrieval()
{
strcpy(Title,"");
Code=0;
}
Retrieval:
:
Retrieval(char*title,longcode)
{
strcpy(Title,title);
Code=code;
}
voidRetrieval:
:
Show()
{
cout<<"资料:
"<
}
classBook:
publicRetrieval//图书类
{
private:
charAuthor[20];//作者名
charIndexCode[10];//内部分类号
public:
Book();
Book(char*author,char*title,char*index,longcode);
voidShow();//显示图书信息
};
Book:
:
Book():
Retrieval()
{
strcpy(Author,"");
strcpy(IndexCode,"");
}
Book:
:
Book(char*author,char*title,char*index,longcode):
Retrieval(title,code)
{
strcpy(Author,author);
strcpy(IndexCode,index);
}
voidBook:
:
Show()
{
cout<<"图书:
"<
< } classMagazine: publicRetrieval//杂志类 { private: intVolume;//卷号 public: Magazine(); Magazine(char*title,intvol,longcode); voidShow();//显示杂志信息 }; Magazine: : Magazine(): Retrieval() { Volume=0; } Magazine: : Magazine(char*title,intvol,longcode): Retrieval(title,code) { Volume=vol; } voidMagazine: : Show() { cout<<"杂志: "< < } 读者类设计如下: //Reader.h classReader//读者类 { private: charName[20];//读者姓名 longCode;//借书证号 Book*books;//所借图书 intCounterB;//已借书数目 Magazine*magazines;//所借杂志 intCounterM;//已借杂志数目 public: Reader(); Reader(char*name,longcode); ~Reader(); voidShow();//显示读者信息 voidShowBooks();//显示所借书 voidShowMagazines();//显示所借杂志 voidAddBook(Bookit);//添加所借书 voidAddMagazine(Magazineit);//添加所借杂志 voidDelBook(Bookit);//归还所借书 voidDelMagazine(Magazineit);//归还所借杂志 }; Reader: : Reader() { strcpy(Name,""); Code=0; books=newBook[5]; CounterB=0; magazines=newMagazine[10]; CounterM=0; } Reader: : Reader(char*name,longcode) { strcpy(Name,name); Code=code; books=newBook[5]; CounterB=0; magazines=newMagazine[10]; CounterM=0; } Reader: : ~Reader() { deletebooks; deletemagazines; } voidReader: : Show() { cout<<"读者: \t"< } voidReader: : ShowBooks() { if(CounterB==0) { cout<<"书已还清! "< return; } for(inti=0;i books[i].Show(); } voidReader: : ShowMagazines() { if(CounterM==0) { cout<<"杂志已还清! "< return; } for(inti=0;i magazines[i].Show(); } voidReader: : AddBook(Bookit) { if(CounterB<5) { books[CounterB]=it; CounterB++; } else { cout<<"您已借满了5本书! "< } } voidReader: : DelBook(Bookit) { for(inti=CounterB;i>0;i--) if(books[i].GetCode()==it.GetCode())break; for(intj=i;j books[j]=books[j+1]; CounterB--; } voidReader: : AddMagazine(Magazineit) { if(CounterM<10) { magazines[CounterM]=it; CounterM++; } else { cout<<"您已借满了10本杂志! "< } } voidReader: : DelMagazine(Magazineit) { for(inti=CounterM;i>0;i--) if(magazines[i].GetCode()==it.GetCode())break; for(intj=i;j magazines[j]=magazines[j+1]; CounterM--; } 测试程序设计如下: //Exam5-7.cpp #include #include #include"Retrieval.h" #include"Reader.h" voidmain(void) { Bookb1("朱战立","C++面向对象程序设计","P306/5",10001); Bookb2("朱战立","数据结构——使用C语言(第3版)","P306/6",10002); Magazinem1("计算机学报",13,20001); Magazinem2("计算机应用",12,20002); Readerr1("张三",30001); Readerr2("李四",30002); r1.Show(); r2.Show(); r1.AddBook(b1); r1.AddBook(b2); r1.ShowBooks(); r2.AddMagazine(m1); r2.AddMagazine(m2); r2.DelMagazine(m1); r2.ShowMagazines(); } 程序运行输出如下: 读者: 张三30001 读者: 李四30002 图书: C++面向对象程序设计朱战立P306/510001 图书: 数据结构——使用C语言(第3版)朱战立P306/610002 杂志: 计算机应用1220002 问题: 进一步分析图书馆的图书和杂志管理和借阅方式,设计一个基本符合图书馆实际工作方式的图书和杂志借阅系统。 .1.2链式堆栈——私有继承举例 私有继承的特点是: 基类的保护成员和公有成员将成为派生类的私有成员。 私有继承的应用意义是: 派生类在利用基类已经设计完成的代码资源的同时,限制派生类的对象调用基类中的公有成员。 【例51.1】先设计一个带头结点的单链表类,再设计一个带头结点的链式堆栈类,要求带头结点的链式堆栈类利用带头结点的单链表类的代码资源。 设计: 带头结点的链式堆栈和带头结点的单链表在结构上完全相同,其构造都是一个由头指针指示的有size个结点的链表,惟一的差别是单链表允许在任意结点位置插入和删除,而链式堆栈只允许在头结点后插入和删除。 带头结点的单链表结构如图5-7(a)所示,带头结点的链式堆栈结构如图5-7(b)所示。 图51.2单链表和链式堆栈 (a)单链表;(b)链式堆栈 单链表类的成员变量包括头指针和结点个数,成员函数包括: 取结点个数、判链表空否、插入结点、删除结点、取结点的数据值。 链式堆栈类的成员变量包括头指针和结点个数,成员函数包括: 取结点个数、判堆栈空否、入栈、出栈、取栈顶结点的数据值。 为了简化链式堆栈类的设计,可以把链式堆栈类设计成单链表类的派生类,这样就可以利用单链表类的代码资源。 以入栈为例,单链表类的插入结点是在参数指定的某个结点后插入一个结点,而链式堆栈类的入栈是在头结点后插入一个结点,因此入栈成员函数就可以用参数值固定为0调用插入结点成员函数来实现。 链式堆栈类的其它成员函数设计方法类同。 由于链式堆栈类只允许在栈顶位置插入结点,不允许在其他位置插入结点,因此,链式堆栈类要私有继承单链表类,这样就能保证外部程序的对象不能在其他位置随意插入结点,从而保证堆栈的正确性。 带头结点的单链表类设计如下: //LinList.h #include #include classListNode//结点类 { friendclassLinList; private: ListNode*next;//指向下一结点的指针 floatdata;//数据元素 public: ListNode(ListNode*ptrNext=NULL)//构造函数,构造头结点 {next=ptrNext;} ListNode(constfloat&item,ListNode*ptrNext=NULL) //构造函数,构造其他结点 { data=item; next=ptrNext; } }; classLinList//单链表类 { private: ListNode*head;//头指针 intsize;//结点个数 voidClearList(void);//清空链表 ListNode*Index(intpos)const;//返回指向第pos个结点的指针 public: LinList(void);//构造函数 ~LinList(void);//析构函数 intListSize(void)const;//取结点个数 intListEmpty(void)const;//判链表空否 voidInsert(constfloat&item,intpos);//插入一个结点 floatDelete(intpos);//删除第pos个结点 floatGetData(intpos)const;//取第pos个结点的data值 }; LinList: : LinList()//构造函数 { head=newListNode;//头指针指向头结点 size=0;//定义size的初值为0 } LinList: : ~LinList(void)//析构函数 { ClearList();//清空链表 deletehead; } voidLinList: : ClearList(void)//清空表为初始化状态 { ListNode*p,*p1; p=head->next;//p指向第一个结点 while(p! =NULL)//释放结点空间直至初始化状态 { p1=p; p=p->next; deletep1; } size=0;//结点个数置为初始化值0 } ListNode*LinList: : Index(intpos)const//返回指向第pos个结点的指针 { if(pos<-1||pos>size) { cout<<"参数pos越界出错! "< exit(0); } if(pos==-1)returnhead;//pos为-1时返回头指针head ListNode*p=head->next;//p指向第一个结点 inti=0;//从0开始计数 while(p! =NULL&&i { p=p->next; i++; } returnp;//返回第pos个结点指针 } intLinList: : ListSize(void)const//取结点个数 { returnsize; } intLinList: : ListEmpty(void)const//判链表空否 { if(size<=0)return1; elsereturn0; } voidLinList: : Insert(constfloat&item,intpos) //在第pos个结点后插入一个元素值为item的新结点 { ListNode*p=Index(pos-1);//p为指向第pos-1个结点指针 //构造新结点newNode,newNode的data域值为item,next域值为p->next ListNode*newNode=newListNode(item,p->next); p->next=newNode;//新结点插入第pos个结点前 size++;//结点个数加1 } floatLinList: : Delete(intpos)//删除第pos个结点 { if(size==0) { cout<<"链表已空无元素可删! "< exit(0); } ListNode*q,*p=Index(pos-1);//p为指向第pos-1个结点指针 q=p->next;//q指向第pos个结点 p->next=p->next->next;//第pos个结点脱链 floatdata=q->data; deleteq;//释放第pos个结点空间 size--;//结点个数减1 returndata;//返回第pos个结点的data域值 } floatLinList: : GetData(intpos)const//取第pos个结点的data值 { ListNode*p=Index(pos);//p指向第pos个结点 returnp->data; } 带头结点的链式堆栈类设计如下: //LinStack.h #include"LinList.h" classLinStack: privateLinList//私有继承 { public: LinStack(void): LinList(){} ~LinStack(void){} intStackSize(void)const//返回堆栈元素个数 {returnListSize();} intStackEmpty(void)const//判堆栈空否 {returnListEmpty();} voidPush(constfloat&item)//入栈 {Insert(item,0);} floatPop(void)//出栈 {returnDelete(0);} floatGetTop(void)const//取栈顶元素 {returnGetData(0);} }; 测试程序设计如下: //Exam5-8.cpp #include"LinStack.h" voidmain(void) { LinStackmyStack; inti; cout<<"初始元素个数: "< for(i=1;i<=5;i++) myStack.Push(i); cout<<"入栈后元素个数: "< cout<<"依次出栈的元素: "; for(i=1;i<=5;i++) cout< cout< cout<<"结束元素个数: "< } 程序运行输出结果为: 初始元素个数: 0 入栈后元素个数: 5 依次出栈的元素: 54321 结束元素个数: 0 私有继承方式可以利用已设计完成的基类代码资源,简化派生类的代码设计,但是,这时所有成员函数的执行都是通过调用基类的成员函数实现的,其时间效率会受到一定的影响。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 西安石油 大学 大二 C+ 面向 对象 程序设计 课件 章程