西安石油大学大二上C++面向对象程序设计课件第5章程序Word下载.docx
《西安石油大学大二上C++面向对象程序设计课件第5章程序Word下载.docx》由会员分享,可在线阅读,更多相关《西安石油大学大二上C++面向对象程序设计课件第5章程序Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
![西安石油大学大二上C++面向对象程序设计课件第5章程序Word下载.docx](https://file1.bdocx.com/fileroot1/2022-11/30/435e6fb9-555c-4df4-b7b8-22c0294c9be4/435e6fb9-555c-4df4-b7b8-22c0294c9be41.gif)
{
strcpy(Title,"
"
);
Code=0;
Retrieval(char*title,longcode)
strcpy(Title,title);
Code=code;
voidRetrieval:
Show()
cout<
<
"
资料:
<
Title<
'
\t'
Code<
endl;
classBook:
publicRetrieval//图书类
private:
charAuthor[20];
//作者名
charIndexCode[10];
//内部分类号
Book();
Book(char*author,char*title,char*index,longcode);
//显示图书信息
Book:
Book():
Retrieval()
strcpy(Author,"
strcpy(IndexCode,"
Book(char*author,char*title,char*index,longcode):
Retrieval(title,code)
strcpy(Author,author);
strcpy(IndexCode,index);
voidBook:
图书:
Author<
<
IndexCode<
classMagazine:
publicRetrieval//杂志类
intVolume;
//卷号
Magazine();
Magazine(char*title,intvol,longcode);
//显示杂志信息
Magazine:
Magazine():
Volume=0;
Magazine(char*title,intvol,longcode):
Volume=vol;
voidMagazine:
杂志:
Volume<
读者类设计如下:
//Reader.h
classReader//读者类
charName[20];
//读者姓名
//借书证号
Book*books;
//所借图书
intCounterB;
//已借书数目
Magazine*magazines;
//所借杂志
intCounterM;
//已借杂志数目
Reader();
Reader(char*name,longcode);
~Reader();
//显示读者信息
voidShowBooks();
//显示所借书
voidShowMagazines();
//显示所借杂志
voidAddBook(Bookit);
//添加所借书
voidAddMagazine(Magazineit);
//添加所借杂志
voidDelBook(Bookit);
//归还所借书
voidDelMagazine(Magazineit);
//归还所借杂志
Reader:
Reader()
strcpy(Name,"
books=newBook[5];
CounterB=0;
magazines=newMagazine[10];
CounterM=0;
Reader(char*name,longcode)
strcpy(Name,name);
~Reader()
deletebooks;
deletemagazines;
voidReader:
读者:
\t"
Name<
ShowBooks()
if(CounterB==0)
{
cout<
书已还清!
return;
}
for(inti=0;
i<
CounterB;
i++)
books[i].Show();
ShowMagazines()
if(CounterM==0)
杂志已还清!
CounterM;
magazines[i].Show();
AddBook(Bookit)
if(CounterB<
5)
{
books[CounterB]=it;
CounterB++;
else
您已借满了5本书!
DelBook(Bookit)
for(inti=CounterB;
i>
0;
i--)
if(books[i].GetCode()==it.GetCode())break;
for(intj=i;
j<
j++)
books[j]=books[j+1];
CounterB--;
AddMagazine(Magazineit)
if(CounterM<
10)
magazines[CounterM]=it;
CounterM++;
您已借满了10本杂志!
DelMagazine(Magazineit)
for(inti=CounterM;
if(magazines[i].GetCode()==it.GetCode())break;
magazines[j]=magazines[j+1];
CounterM--;
测试程序设计如下:
//Exam5-7.cpp
iostream.h>
#include"
Retrieval.h"
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
stdlib.h>
classListNode//结点类
friendclassLinList;
ListNode*next;
//指向下一结点的指针
floatdata;
//数据元素
ListNode(ListNode*ptrNext=NULL)//构造函数,构造头结点
{next=ptrNext;
ListNode(constfloat&
item,ListNode*ptrNext=NULL)
//构造函数,构造其他结点
data=item;
next=ptrNext;
classLinList//单链表类
ListNode*head;
//头指针
intsize;
//结点个数
voidClearList(void);
//清空链表
ListNode*Index(intpos)const;
//返回指向第pos个结点的指针
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(void)//析构函数
ClearList();
//清空链表
deletehead;
voidLinList:
ClearList(void)//清空表为初始化状态
ListNode*p,*p1;
p=head->
next;
//p指向第一个结点
while(p!
=NULL)//释放结点空间直至初始化状态
p1=p;
p=p->
deletep1;
//结点个数置为初始化值0
ListNode*LinList:
Index(intpos)const//返回指向第pos个结点的指针
if(pos<
-1||pos>
size)
参数pos越界出错!
exit(0);
if(pos==-1)returnhead;
//pos为-1时返回头指针head
ListNode*p=head->
//p指向第一个结点
inti=0;
//从0开始计数
=NULL&
&
pos)//寻找第pos个结点
i++;
returnp;
//返回第pos个结点指针
intLinList:
ListSize(void)const//取结点个数
returnsize;
ListEmpty(void)const//判链表空否
if(size<
=0)return1;
elsereturn0;
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)
链表已空无元素可删!
ListNode*q,*p=Index(pos-1);
//p为指向第pos-1个结点指针
q=p->
//q指向第pos个结点
next=p->
next->
//第pos个结点脱链
floatdata=q->
data;
deleteq;
//释放第pos个结点空间
size--;
//结点个数减1
returndata;
//返回第pos个结点的data域值
GetData(intpos)const//取第pos个结点的data值
ListNode*p=Index(pos);
//p指向第pos个结点
returnp->
带头结点的链式堆栈类设计如下:
//LinStack.h
LinList.h"
classLinStack:
privateLinList//私有继承
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
LinStack.h"
LinStackmyStack;
inti;
初始元素个数:
myStack.StackSize()<
for(i=1;
=5;
myStack.Push(i);
入栈后元素个数:
依次出栈的元素:
;
myStack.Pop()<
;
结束元素个数:
程序运行输出结果为:
5
54321
私有继承方式可以利用已设计完成的基类代码资源,简化派生类的代码设计,但是,这时所有成员函数的执行都是通过调用基类的成员函数实现的,其时间效率会受到一定的影响。