西安石油大学大二上C++面向对象程序设计课件第5章程序.docx

上传人:b****3 文档编号:4419552 上传时间:2022-12-01 格式:DOCX 页数:15 大小:25.21KB
下载 相关 举报
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx_第1页
第1页 / 共15页
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx_第2页
第2页 / 共15页
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx_第3页
第3页 / 共15页
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx_第4页
第4页 / 共15页
西安石油大学大二上C++面向对象程序设计课件第5章程序.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

西安石油大学大二上C++面向对象程序设计课件第5章程序.docx

《西安石油大学大二上C++面向对象程序设计课件第5章程序.docx》由会员分享,可在线阅读,更多相关《西安石油大学大二上C++面向对象程序设计课件第5章程序.docx(15页珍藏版)》请在冰豆网上搜索。

西安石油大学大二上C++面向对象程序设计课件第5章程序.docx

西安石油大学大二上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

私有继承方式可以利用已设计完成的基类代码资源,简化派生类的代码设计,但是,这时所有成员函数的执行都是通过调用基类的成员函数实现的,其时间效率会受到一定的影响。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1