实验一.docx
《实验一.docx》由会员分享,可在线阅读,更多相关《实验一.docx(16页珍藏版)》请在冰豆网上搜索。
实验一
电子科技大学
实验报告
学生姓名:
xxxx学号:
xxx指导教师:
xxx
实验地点:
xx实验时间:
xx
一、实验室名称:
软件实验室
二、实验项目名称:
面向对象程序设计—数据封装
三、实验学时:
6
四、实验原理:
数据封装将一组数据和这组数据有关的操作集合封装在一起,形成一个能动的实体,称为对象。
用户不必知道对象行为的实现细节,只需根据对象提供的外部特性接口访问对象。
面向对象技术试图通过建立一个合适的数据类型,将描述对象的属性(数据)和行为(函数)结合在一起,形成一个新的抽象数据类型,称为类类型(class)。
类是C++的封装机制,其中包括了数据成员和成员函数。
在C++类中,能确保数据只能由类中的成员函数进行访问和处理。
在任何时候,都可以自由地改变数据成员的组织形式,只需改变成员函数的实现细节。
由于这些成员函数的接口不改变,系统其他部分的程序(及使用者)就不会由于改动而受到影响。
类的概念将数据和与这个数据有关的操作集合封装在一起,建立了一个定义良好的接口,人们只关心其使用,不关心其实现细节。
这反应了抽象数据类型的思想。
五、实验目的:
本实验通过编写一些简单的程序,使学生掌握数据封装的概念,并能熟练编写C++类,培养理论联系实际和自主学习的能力,提高程序设计水平。
六、实验内容:
一位小学教师Ken希望完成这样的任务:
针对于小学生正在学习四边形(quadrangle)的特性,编写一个小软件,能够随机在屏幕上显示矩形(rectangle)、正方形(square)、平行四边形(parallelogram)、梯形(trapezoid)和菱形(diamond)五种形体之一,同时显示该形体的特性和关键数据(随机产生),学生复习形体的特性,然后根据给出的关键数据计算形体的面积,软件判断其结果的正确性。
在学习过程中,软件记录产生的每一个形体,在学生选择不再继续后,将其学习的过程重放一遍,用以重温,加深印象。
根据Ken老师的要求,需要至少编写六个类:
1)Rect//注意:
类名不要使用Rectangle
2)Square
3)Parallelogram
4)Trapezoid
5)Diamond
6)List
其中,前五个类用于描述五种形体。
五种形体不用顶点坐标的表示形式,而只是简单地用它们的特征值表示。
例如:
矩形、平行四边形用长和高表示;正方形用边长表示;梯形用两条平行边长和高表示;菱形用两条对象线长表示。
要求为这五种形体编写相应的类,类中包括至少如下数据成员和成员函数:
1)特征值,例如长和宽等;
2)stringname;用于存储形体的类别。
类别的名字就是类的名字。
例如:
Rect类的类别名就是“Rectangle”;
3)doublearea();用于求形体的面积;
4)voiddraw();用于绘制形体。
不要求用图形的方式画图形,只需要简单地打印出形体的类别和特征值;
5)构造(包括拷贝构造)函数和析构函数。
构造函数要带有相应的参数以能够用指定特征值初始化形体对象。
此外,List类用于存储各种形体。
形体的产生可以通过随机的方式完成。
不过,List类的push_back()成员的代码需要自行完成。
附件中给出了List类的大部分代码。
重温过程实际上就是遍历List类对象的过程。
这个过程可能有些复杂,附件中也给出了遍历的示例代码。
附件中给出了其它需要的示例代码,以及解题思路,请参阅。
注:
请将此实验编写的代码完整保存,此后的两项实验都要以本次实验的代码为基础。
实验四属于选作实验。
七、实验器材(设备、元器件):
PC机一台,装有C/C++语言集成开发环境。
八、实验步骤:
#include
#include
#include
#include
#include
usingnamespacestd;
classQuadrangle
{
public:
stringname;//形体的标识
};
typedefQuadrangle*QUADPTR;
classRect
{
public:
stringname;//形体的标识(矩形)
Rect(intw=5,inth=7,stringnm="Rectangle")
{
name=nm;
height=h;
width=w;
}
~Rect(){}
voiddraw()const;
doublearea()const;
stringwhat()const;
int&Width();//获取矩形的宽。
如果是梯形,还需要一个成员int&Width2()来获取另一条平行边的长度
int&Height();//获取矩形的高
private:
intwidth,height;//高和宽
};
voidRect:
:
draw()const
{
cout<width="<}
stringRect:
:
what()const
{
returnname;
}
doubleRect:
:
area()const
{
returnwidth*height;
}
classSqu
{
public:
stringname;//形体的标识(正方形)
Squ(intlength1=5,stringnm="Square")
{
name=nm;
length=length1;
}
~Squ(){}
voiddraw()const;
doublearea()const;
stringwhat()const;
int&getlength();//获取正方形的边长。
如果是梯形,还需要一个成员int&Width2()来获取另一条平行边的长度
private:
intlength;//边长
};
voidSqu:
:
draw()const
{
cout<="<}
stringSqu:
:
what()const
{
returnname;
}
doubleSqu:
:
area()const
{
returnlength*length;
}
classPara
{
public:
stringname;//形体的标识(平行四边形)
Para(intw=5,inth=7,stringnm="Parallelogram")
{
name=nm;
width=w;
height=h;
}
~Para(){}
voiddraw()const;
doublearea()const;
stringwhat()const;
int&Width();//获取平行四边形的长。
如果是梯形,还需要一个成员int&Width2()来获取另一条平行边的长度
int&Height();//获取平行四边形的高
private:
intwidth,height;//高和长
};
voidPara:
:
draw()const
{
cout<width="<}
stringPara:
:
what()const
{
returnname;
}
doublePara:
:
area()const
{
returnwidth*height;
}
classDia
{
public:
stringname;//形体的标识(菱形)
Dia(intlength=5,intlength3=7,stringnm="Diamond")
{
name=nm;
length1=length;
length2=length3;
}
~Dia(){}
voiddraw()const;
doublearea()const;
stringwhat()const;
double&Length1();//获取菱形的对角线的长。
如果是梯形,还需要一个成员int&Width2()来获取另一条平行边的长度
double&Length2();
private:
doublelength1,length2;
};
voidDia:
:
draw()const
{
cout<length1="<}
stringDia:
:
what()const
{
returnname;
}
doubleDia:
:
area()const
{
return(length1*length2)/2;
}
classTra
{
public:
stringname;//形体的标识(梯形)
Tra(intw1=5,intw2=4,inth=7,stringnm="Trapezoid")
{
name=nm;
width1=w1;
width2=w2;
height=h;
}
~Tra()
{}
voiddraw()const;
doublearea()const;
stringwhat()const;
double&Width1();//梯形的长。
如果是梯形,还需要一个成员int&Width2()来获取另一条平行边的长度
double&Width2();
double&Height();//获取梯形的高
private:
doublewidth1,width2,height;
};
voidTra:
:
draw()const
{
cout<width1="<}
stringTra:
:
what()const
{
returnname;
}
doubleTra:
:
area()const
{
return(width1+width2)*height/2;
}
typedefvoid(*ACCESSFUN)(QUADPTR);
classList
{
private:
struct_Node
{
QUADPTRdata;
_Node*next;
}*head,*tail;//链表的头尾指针
typedef_Node*_range;
size_tlen;//链表中节点的数目,即链表的长度
public:
List();//平凡构造函数
List(constList&l);//复制构造函数
~List();
voidpush_back(constQUADPTRquad);//尾部添加
size_tsize();//获取链表的长度
voidtraverse(ACCESSFUNf);//遍历
};
List:
:
List():
head(NULL),tail(NULL){}
List:
:
List(constList&l)
{
head=tail=NULL;
_Node*p=l.head;
while(p!
=NULL)
{
this->push_back(p->data);
p=p->next;
}
}
List:
:
~List()
{
_Node*p=head,*q;
while(p!
=NULL)
{
q=p;
p=p->next;
deleteq;
}
}
voidList:
:
push_back(constQUADPTRquad)
{
_Node*p=new_Node;
p->data=const_cast(quad);
p->next=NULL;
if(tail==NULL)
head=tail=p;
else
{
tail->next=p;
tail=p;
}
}
size_tList:
:
size()
{
_Node*p=head;
size_tlen=0;
while(p!
=NULL)
{
p=p->next;
++len;
}
returnlen;
}
voidList:
:
traverse(ACCESSFUNf)
{
_rangep=head;//请自行添加初始化部分
while(p!
=NULL)
{
f(p->data);
p=p->next;//请自行添加指针移动部分
}
}
voidaccess(QUADPTRquad)
{
if(quad->name=="Rectangle")
{
Rect*p=reinterpret_cast(quad);
p->draw();
cout<<"area="<area()<}
elseif(quad->name=="Square")
{
Squ*p=reinterpret_cast(quad);
p->draw();
cout<<"area="<area()<}
elseif(quad->name=="Parallelogram")
{
Para*p=reinterpret_cast(quad);
p->draw();
cout<<"area="<area()<}
elseif(quad->name=="Diamond")
{
Dia*p=reinterpret_cast(quad);
p->draw();
cout<<"area="<area()<}
elseif(quad->name=="Trapezoid")
{
Tra*p=reinterpret_cast(quad);
p->draw();
cout<<"area="<area()<}
}
intmain()
{
Listlist;
srand(unsigned(time(NULL)));
cout<<"小学生学习进程"<done:
inti=(rand()%5);
if(i==0)
{
Rect*re=newRect();
re->draw();
list.push_back(reinterpret_cast(re));
cout<<"输入其面积计算结果:
";
for(;;)
{
doubleanswer=0.0;
cin>>answer;
if(answer!
=re->area())
cout<<"结果错误,请重新计算:
";
else
{
cout<<"结果正确"<break;
}
}
}
elseif(i==1)
{
Dia*di=newDia();
di->draw();
list.push_back(reinterpret_cast(di));
cout<<"输入其面积计算结果:
";
for(;;)
{
doubleanswer=0.0;
cin>>answer;
if(answer!
=di->area())
cout<<"结果错误,请重新计算:
";
else
{
cout<<"结果正确"<break;
}
}
}
elseif(i==2)
{
Para*pa=newPara();
pa->draw();
list.push_back(reinterpret_cast(pa));
cout<<"输入其面积计算结果:
";
for(;;)
{
doubleanswer=0.0;
cin>>answer;
if(answer!
=pa->area())
cout<<"结果错误,请重新计算:
";
else
{
cout<<"结果正确"<break;
}
}
}
elseif(i==3)
{
Tra*tr=newTra();
tr->draw();
list.push_back(reinterpret_cast(tr));
cout<<"输入其面积计算结果:
";
for(;;)
{
doubleanswer=0.0;
cin>>answer;
if(answer!
=tr->area())
cout<<"结果错误,请重新计算:
";
else
{
cout<<"结果正确"<break;
}
}
}
elseif(i==4)
{
Squ*sq=newSqu();
sq->draw();
list.push_back(reinterpret_cast(sq));
cout<<"输入其面积计算结果:
";
for(;;)
{
doubleanswer=0.0;
cin>>answer;
if(answer!
=sq->area())
cout<<"结果错误,请重新计算:
";
else
{
cout<<"结果正确"<break;
}
}
}
intanswer1;
cout<<"小朋友是要继续学习呢还是开始复习呢?
(如果继续学习的话请输入1,如果是想要复习的话请输入2):
";
cin>>answer1;
if(answer1==1)
gotodone;
elseif(answer1==2)
{
cout<<"小学生复习进程"<list.traverse(access);
}
system("pause");
return0;
}
九、实验数据及结果分析:
十、实验结论:
实验运行成功,通过随机产生五种形体,让小学生根据其给定数据计算形体面积,并验证其正确性。
十一、总结及心得体会:
通过此次实验,编写一些简单的程序,使我更好的掌握数据封装的概念,并且熟练编写C++类,培养理论联系实际和自主学习的能力。