文档库 最新最全的文档下载
当前位置:文档库 › c++继承习题

c++继承习题

c++继承习题
c++继承习题

一、实验目的:

(1)学习定义和使用类的继承关系,定义派生类。

(2)熟悉不同继承方式下对基类成员的访问控制。

(3)掌握继承的其他有关知识

二、实验题目(此部分必做):

1.题目1

a)定义一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成

员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把age改为公有

成员变量,还会有问题吗?编程试试看。

b)定义一个基类BaseClass,有整型成员变量Number ,构造其派生类

DerivedClass,观察构造函数和析构函数的执行情况。

c)定义一个车(vehicle)基类,具有MaxSpeed、Weight等成员变量,Run、Stop

等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类。自行车类有高

度(height)等属性,汽车类有座位数(SeatNum)等属性。从bicycle和motorcar

派生出摩托车(motorcycle)类,在继承过程中,注意把vehicle设置为虚基类。

如果不把vehicle设置为虚基类,会有什么问题?编程试试看。

实验提示:

(1)编写程序定义基类Animal,成员变量age定义为私有的。构造派生类dog,在其成员函数SetAge(int n)中直接对age赋值时,会出现类似以下的错误提示:

error C2248:’age’:cannot access private member declared in class ‘Animal’

error C2248:’age’:cannot access private member declared in class ‘Animal’

把age改为公有成员变量后重新编译就可以了。程序名为:lab7_1.cpp

(2)编写程序定义一个基类BassClass,构造其派生类DerivedClass,在构造函数和析构函数中用cout输出提示信息,观察构造函数和析构函数的执行情况。程序名为:lab7_2.cpp。用debug功能跟踪程序的执行过程,观察基类和派生类的构造函数和析构函数的执行情况。

(4)写程序定义一个车(vehicle)基类,由此派生出自行车(bicycle)类、汽车类(motorcar)

类,注意把vehicle派生为虚基类。再从bicycle和motorcar派生出摩托车(motorcycle)类,在main()函数中测试这个类。程序名为:lab7_3.cpp。

编译成功后,把vehicle设置为非虚基类,再编译一次,此时系统报错,无法编译成功。

这是因为若不把vehicle设置为虚基类,会出现二义性错误,程序不能成功编译。

2、定义一个大学生类student,函数私有数据成员:姓名、学号、校名,并为它定义带参数的构造函数、参数带缺省值的构造函数和输出数据成员值的print()公有成员函数,另定义研究生类,它以公有继承方式派生于类student,新增加“研究方向、导师名”两个私有数据成员,并定义带参数的构造函数和输出研究生数据的print()公有成员函数。在main()函数中定义基类和派生类对象,对类进行测试。

3、建立普通的基类building,用于存储一座楼房的层数、房间数和它的总平方面积。建立有派生类house,继承building,并存储卧室和浴室的数量。另建立派生类office,继承building,存储工作人员和电话的数目。设计程序,并测试上述三个类。

基类定义参考如下:

#include

class Building

{

int layernumber;

int housenum;

float sumarea;

public:

Building();

Building(int m,int n,float s)

{

cout<<"base constructor called."<

layernumber=m;housenum=n;sumarea=s;

}

void print()

{

cout<<"this is a "<

cout<<"there are "<

cout<<"And total area is "<

}

};

参考测试程序:

void main()

{

Building build1(18,360,8000);

build1.print();

House house(6,24,2880,4,2);

house.print();

Office office(18,360,8000,4,4);

office.print();

}

程序执行输出结果如下:

base constructor called.

this is a 18-story building

there are 360 houses

And total area is 8000

base constructor called.

House constructer called.

this is a 6-story building

there are 24 houses

And total area is 2880

bedroomnum=4

bathroomnum=2

base constructor called.

Office Constructor called. this is a 18-story building there are 360 houses And total area is 8000 stuffnum=4

telnum=4

4、题目2:从下图可以看出一个立方体Box 可以视为是在一个矩形Rectangle 的相互正交的长length 和宽width 的基础上增加一维与length 和width 相互正交的高height 而生成的。Box 的体积可以视为是由length 和width 确定的矩形面积沿正交轴在[0, height ]区间进行积分获得的;Box 的面积可以视为是由length 和width 确定的矩形周长沿正交轴在[0, height ]区间进行积分的结果+两倍的矩形面积获得的。

要求: 1.定义具有继承关系的矩形类Rectangle 和立方体类Box 。两个类中除了具有共同的 属性length 和width ,还具有相同的接口(公有成员函数)Area (计算矩形面积 或立方体面积),Perimeter (计算矩形周长或立方体周长),Diagonal (计算矩形 对角线或立方体对角线的长度),GetLength (获取长度属性),GetWidth (获取宽 度属性),SetLength (设置长度属性)和SetWidth (设置宽度属性)。除此之外, 立方体类Box 还需要增加height 属性和接口函数Volume (计算立方体的体积), GetHeight (获取高度属性)和SetHeight (设置高度属性)。 2. 在主函数main ()中对矩形类Rectangle 和立方体类Box 进行如下测试: ①通过键盘输入长、宽和高,并以所输入的值创建3个Rectangle 对象和1个Box 对象。 ②通过上述对象分别计算并格式显示3个矩形和1个立方体的各项形态信息。矩 形的形态信息包括:长、宽、面积、周长和对角线;立方体的形态信息包括:长、 宽、高、体积、面积、周长和对角线。 ③通过键盘输入新的长、宽和高,由并以所输入的值修改已创建的3个Rectangle 对象和1个Box 对象的相应属性。 ④重新分别计算并格式显示3个矩形和1个立方体的各项形态信息。 3. 要求编写编程文档,文档内容包括:

① 绘制Rectangle 和Box 类图,以及它们之间的静态关联图。

② Rectangle 和Box 类的定义描述。

提示:立方体的周长定义为各棱长的和,立方体的对角线定义为立方体中不在同一矩形表面的两个顶点间的连线(矩形的对角线是不在同一边上的两个顶点间的连线)。

width

三、课外选作题

字典Dictionary是一个有由单词组成的集合。该集合中存放这些单词的结构可以有多种,其中链表是一种较为简单和高效的结构。一个由存放单词的结点wordNode组成的单词链表WordList与字典Dictionary之间的差异仅在于Dictionary中不允许有重复单词的结点。其中存放单词的结点wordNode是构成字典的最基本数据单位,对结点对象的访问是十分频繁的,因此可以将单词结点wordNode定义为如下的结构:struct wordNode

{

stringname; // 单词名。

Type type; // 单词类型包括名词noun、及物动词vt、不及物动词vi、

//形容词adj、副词adv、介词prep、代词pron、连词conj、

//数词num和感叹词inter),一个单词可以是单一类型或//

多类型。

MeanList *mean [10]; // 单词的全部含义描述。每个单词的每个词性都允许有多

//个含义描述。

wordNode *next; // 指向下一个单词结点。

wordNode() // 构造函数

{

for(int i = 0; i < 10; i++)

mean[i] = NULL;

next = NULL;

}

~wordNode() // 析构函数

{

for(int i = 0; i < 10; i++)

if(mean[i]) delete mean[i];

}

};

wordNode的词名成员name是string类对象,该类的定义和功能已经在5.3题进行了详细说明(以下相同)。

wordNode的词性成员type的类型wordType可以定义为一个联合(union),便于对单词类型的高效访问。该联合和联合中成员类型可以定义如下:

struct sortType

{

unsigned noun: 1; // 名词类型

unsigned vt: 1; // 及物动词类型

unsigned vi: 1; // 不及物动词类型

unsigned adj: 1; // 形容词类型

unsigned adv: 1; // 副词类型

unsigned prep: 1; // 介词类型

unsigned pron: 1; // 代词类型

unsigned conj: 1; // 连接词类型

unsigned num: 1; // 数词类型

unsigned inter: 1; // 感叹词类型

unsigned non: 6; // 未使用

};

union Type

{

sortTypesort; // 分类型访问

short whole; // 整体访问

Type(){whole = 0;} // 构造函数

};

wordNode的词义成员mean是对应每个词性的词义链表MeanList类型的指针数组,数组中每一个元素指向该单词某一个词性的词义链表。该链表中的结点也可以定义为如下结构:

struct wordMean

{

stringdepict; // 单词含义描述字串

wordMean* next; // 指向下一个词义

};

要求:

1.使用结构类型wordMean定义一个词义链表类型MeanList用于对单词的某一个词

性类型的词义链表的创建和访问。为此,MeanList应包括如下属性和操作:

①属性:

·链表头属性head:指向词义链表的头结点,因此该属性应该是wordMean 类型的指针。该指针初始化时应为0,表示链表为空。

②操作:

·构造操作:设置head = 0。

·析构操作:如果链表不是空,则遍历链表,删除所有结点。

·插入操作Insert:向词义链表中插入一个新词义结点wordMean类型对象。

·判空操作Empty:根据head的值判定词义链表是否为空(true:空,false: 不空),并返回标志。

·查询操作Contain:查询链表中是否由参数指定的(string类型)词义,如果存在返回该词义结点的地址,否则返回0。

·显示一条词义操作ItemShow:格式输出显示一个词义结点中词义条目。

·显示全部词义操作AllShow:格式输出显示链表中的所有词义条目。

2.使用结构类型wordNode定义一个词义链表类型WordList用于对单词的某一个词

性类型的词义链表的创建和访问。为此,WordList应包括如下属性和操作:

①属性:

·链表头属性head:指向词义链表的头结点,因此该属性应该是wordNode 类型的指针。该指针初始化时应为0,表示链表为空。

②操作:

·构造操作:设置head = 0。

·析构操作:如果链表不是空,则遍历链表,删除所有结点。

·插入操作Insert:向词义链表中插入一个新词义结点wordNode类型对象。

·判空操作Empty:根据head的值判定词义链表是否为空(true:空,false: 不空),并返回标志。

·查询操作Contain:查询链表中是否由参数指定的(string类型)词名,如果

存在返回该词义结点的地址,否则返回0。

·显示一条词义操作ItemShow :格式输出显示一个词义结点中词义条目。 ·显示全部词义操作AllShow :格式输出显示链表中的所有词义条目。

由WordList 构造的单词链表在物理结构上如下面的示意图所示:

3.在单词链表WordList 的基础上派生字典类Dictionary 。根据对字典的操作要求,

需要在Dictionary 中重新定义和增加的以下操作:

①重新定义字典要求的插入操作Insert :该操作应在WordList ::Insert 操作的基

础上,禁止相同的单词被插入同一部字典中。注意,如果欲插入的单词已在词典 中,应显示恰当的提示信息。

②查找并显示字典中某类单词子集操作ShowByType :该操作的功能是在字典中 查询所有具有指定词性类型(通过参数传递词性类型)的单词。如果词典中有指 定词性类型的单词,则顺序显示所有被查询到的单词的相关信息(单词名、指定 词性类型的所有词义条目等);如果词典中没有指定词性类型的单词,则显示恰 当的提示信息。

③查找并显示指定词义的同义单词子集操作ShowByMean :该操作的功能是在字 典中查询所有具有指定词义(通过参数传递词义)的单词。如果词典中有指定词 义的单词,则顺序显示所有被查询到的单词的相关信息(单词名、所有满足指定 词义的相关词义条目等);如果词典中没有指定词性类型的单词,则显示恰当的 提示信息。

④显示字典中全部单词信息操作ShowAll :遍历词典中的全部单词结点,并顺序 显示每个单词的全部信息。

4. 在主函数main ()中创建一个英汉词典English_Chinese ,并通过该词典对象对词典

类Dictionary的各项功能进行如下测试:

①向English_Chinese中插入至少10个单词,每个被插入的单词应具有两种以

上词性类型,每种词性应具有两条以上词义,所有被插入单词的词性种类应覆盖词典能包括的所有词性类型。注意,在插入操作中应测试是否能禁止相同的单词被插入。

②格式显示词典中的所有单词信息。

③通过菜单选择结构,为用户提供按指定的词性或词义查询词典中符合条件的单词

子集的操作功能,直至选择退出操作。

5. 要求编写编程文档,文档内容包括:

①绘制MeanList、WordList和Dictionary类的类图,以及它们之间的静态关联

图。

②MeanList、WordList和Dictionary类的定义描述。

③单词链表WordList的操作Insert以及词典Dictionary的各个操作的算法描述。

④main()的流程图。

提示:

1.为了使向词典插入单词的程序代码具有良好的结构,建议将要插入的单词信息先组

织成具有确定分段格式的字符串,存放在一个二维字符数组中;然后在一个恰当的程序结构中顺序对字符数组的每一个单词信息串进行解析,并将解析获得的单词信息组织成一个完整的单词结点插入词典。所谓具有确定分段格式的单词信息字符串是将单词的词名、词性、词义信息和各种确定的分隔符,按照一定的语法规则组织而成。确定组成单词信息字符串的语法规则的原则是无歧义性、易于解析,例如:单词名{词性名|词义条目|词义条目|…|词义条目}{词性名|词义条目|词义条目|…|

词义条目|}…{词性名|词义条目|词义条目|…|词义条目}

其中分隔符的含义如下:

①词性分隔符:{和}

②词义分隔符:|

按照这样的语法规则,单词automatic的信息被组织成如下字符串:

automatic{adj|自动的|无意识的}{noun|自动装置|自动枪(或炮)}

2. 使用union类型Type定义wordNode::type的优点是便于高效对该属性访问和使

用。例如,在解析得到单词automatic的词性adj时,便通过type.sort.adj = 1设置相应的词性特征位;在判断一个单词的词性或顺序显示一个单词的词义时,又可以提取的词性特征位,确定该单词是否具有该词性,例如,通过type.whole&0x8 提取单词automatic的adj词性特征位。定义一个词性特征位值和词性名之间的映射:struct map { short eigenvalue; char name[6]; };并使用映射类型定义一个数组:maptype[10] = {{0x1,”noun”},{0x2,”vt”},{0x4,”vi”},{0x8,”adj”},{0x10,”adv”},

{0x11,”prep”},{0x12,”pron”},{0x14,”conj”},{0x18,”inter”},{0x20,”num”}};借助该映射数组,可以方便地完成从词性特征位获得对应的词性名,或从词性名获得对应的词性特征位。

难度等级:*****

相关文档