CPP实训4qR.docx
《CPP实训4qR.docx》由会员分享,可在线阅读,更多相关《CPP实训4qR.docx(16页珍藏版)》请在冰豆网上搜索。
CPP实训4qR
第4章面向对象基本概念与类实训
类(class)是用户定义的一种新的数据类型,本章将通过做习题和上机实验,学会怎样定义简单的类。
4.1典型习题解答
【例4.1】解释类和对象有什么区别?
【解答】对象是描述客观事物的一个实体,它是构成信息系统的一个基本单位。
对象由对象名、一组属性和一组操作构成,属性由数据表示,操作由函数实现。
类实质上是定义了一种对象类型,它描述了属于该类型的所有对象的属性和操作。
对象是类的实例。
【例4.2】写出类定义的语法结构。
【解答】
class<类名>{
private:
<私有的数据和函数>
protected:
<保护的数据和函数>
public:
<公有的数据和函数>
};
类的定义包括了4部分:
⑴关键字class和类名,类名是程序员为类起的名字,可以用除关键字以外的任何字符串表示;
⑵左花括号‘{’;
⑶声明数据和函数,数据就是用类型说明C++变量,函数就是一般的C++函数;
⑷右花括号‘}’和分号‘;’。
【例4.3】C++关键字private和public有什么作用?
【解答】公有成员用public关键字声明,它定义了类的外部接口。
私有成员用private关键字声明,它定义了类的内部使用的数据和函数。
【例4.4】公有成员和私有成员有什么区别?
【解答】只有公有成员才能被用户程序直接访问,私有成员只能被自己所属类的成员函数访问。
【例4.5】说明类A的功能:
classA{
private:
intx,y;
public:
voidask1(inta=0,intb=0);
intask2();
voidask3();
};
voidA:
:
ask1(inta,intb){x=a;y=b;}
intA:
:
ask2()
{if(x>y)returnx;
elsereturny;
}
voidA:
:
ask3(){cout<<”x=”<【解答】定义了一个类,类名为A,类A中有2个整型数据成员,它们都有私有数据;类A中有3个公有函数:
ask1(inta=0,intb=0)、ask2()和ask3(),其中ask1(inta=0,intb=0)实现将a的值赋给x,b的值赋给y,若参数b,或参数a、b空缺时,其默认值为0;ask2()是找出私有数据x、y中最大值,将这个最大值作为这个函数的返回结果;ask3()实现输出x和y。
【例4.6】说明类B的功能:
classB{
private:
intx,y;
public:
voidask1(int,intb=0);
voidask2();
voidask3();
};
voidB:
:
ask1(inta,intb){x=b;y=a;}
voidB:
:
ask2()
{intz;
if(x}
voidB:
:
ask3(){cout<<”x=”<【解答】定义了一个类,类名为B,类B中有2个整型数据成员x和y,它们都有私有数据;类B中有3个公有函数:
ask1(inta,intb=0)、ask2()和ask3(),其中ask1(inta,intb=0)实现将a的值赋给y,b的值赋给x,若参数b空缺时,b的默认值为0;ask2()是交换私有数据x、y中的值;ask3()实现输出x和y。
【例4.7】说明类C的功能:
classC{
private:
intx,y;
public:
voidask(int,int);
voidask(int);
voidask();
}
voidC:
:
ask(inta,intb){x=a;y=b;}
voidC:
:
ask(inta){x=a;}
voidC:
:
ask(){cout<<”x=”<【解答】定义了一个类,类名为C,类C中有2个整型数据成员x和y,它们都有私有数据;类C中有3个重载的公有函数:
ask(int,int)、ask(int)和ask(),其中ask(inta,intb)实现将a的值赋给x,b的值赋给y;ask(inta)是将a的值赋给x;ask()实现输出x和y。
【例4.8】说明类D的功能:
classD{
private:
intx;
floaty;
public:
voidask(int);
voidask(float);
voidask();
}
voidD:
:
ask(inta){x=a;}
voidD:
:
ask(floatb){y=b;}
voidD:
:
ask(){cout<<”x=”<【解答】定义了一个类,类名为D,类D中有2个数据成员x和y,它们都有私有数据,x为整型,y为实型;类D中有3个重载的公有函数:
ask(inta)、ask(floatb)和ask(),其中ask(inta)实现将a的值赋给x;ask(floatb)实现将b的值赋给y;ask()实现输出x和y。
【例4.9】设计一个表示猫的类,包括猫的颜色、体重、年龄等数据,具有设置猫的颜色,修改和显示猫的体重、年龄等操作。
【解答】设计猫类的类名为Cat,猫类Cat有3个数据成员,颜色用字符串color[7],可以存放3个汉字,体重用实型数weight表示,年龄用整型数age表示,为了数据的安全性,Cat的3个数据成员全部为私有的。
对猫的属性数据的设置和修改PutColor为设置和修改颜色,PutWeight为设置和修改体重,PutAge为设置和修改年龄,它们都设置为公有函数,还要有一个1次设置3个参数的函数SetCat。
设计函数Display输出猫的信息。
表示猫的类设计如下:
classCat{
intage;
charcolor[7];
floatweight;
public:
voidSetCat(char*s=”黄”,floatw=1,inta=1);
voidPutColor(char*);
voidPutWeight(float);
voidPutAge(int);
voidDisplay();
};
voidCat:
:
SetCat(char*s,floatw,inta)
{//猫的默认颜色为黄、体重1kg、年龄1岁
age=a;weight=w;
strcpy(color,s);
}
voidCat:
:
PutColor(char*s)
{strcpy(color,s);}
voidCat:
:
PutWeight(floatw){weight=w;}
voidCat:
:
PutAge(inta){age=a;}
voidCat:
:
Display()
{cout<<”\n这只猫是一只”<cout<<”体重”<cout<<”年龄”<”<}
若猫的颜色是白色,重2.3kg,2岁,Display函数将会显示:
这只猫是一只白色的猫,体重2.3千克,年龄2岁。
【例4.10】设计一个表示学习成绩的类,至少包括三门课程的成绩,可以设置、显示每门课程的成绩,可以计算、显示平均成绩。
【解答】表示学习成绩的类简称为成绩类,设计成绩类的类名为Grade,成绩类Grade的数据成员,应该包括学生的学号和姓名,因为可能有重名的学生,所以用学号作为唯一代表一个学生的关键字,假设学号全是9个字符,用字符串Number[10]表示,姓名最多为4个汉字,用字符串Name[9]表示,可以存放4个汉字。
假设有3门课,分别为C++程序设计语言,用整型变量Cpp表示;计算机原理,用整型变量Computer表示;数据库,用整型变量DataBase表示。
平均成绩用实型变量Average表示。
为了Grade类数据的安全性,数据成员全部为私有的,对成绩类的属性数据用一些函数进行设置和修改,PutNo为设置和修改学号,PutName为设置和修改姓名,PutCpp为设置和修改C++程序设计语言的成绩,PutCom为设置和修改计算机原理的成绩,PutData为设置和修改数据库的成绩,还有一个同时设置所有5个参数的函数SetGrade,它们都设置为公有函数。
计算平均成绩的函数为Calc,设计函数Display输出成绩。
有时可能要查看某个学生的成绩,所以设计比较学号的函数为ComNo,设计比较姓名的函数为ComName,GetCpp为读取C++程序设计语言的成绩,GetCom为读取计算机原理的成绩,GetData为读取数据库的成绩,设计读取平均成绩的函数为GetAve。
计算平均成绩只是在类的内部实现,所以设计为私有函数,其它函数都设计为公有函数。
表示学习成绩的类设计如下:
classGrade{
charNumber[10];
charName[9];
intCpp,Computer,DataBase;
floatAverage;
voidCalc();
public:
voidPutNo(char*);
voidPutName(char*);
voidPutCpp(intx=60);
voidPutCom(intx=60);
voidPutData(intx=60);
voidSetGrade(char*s1="123456789",char*s2="李华",
intx=60,inty=60,intz=60);
intComNo(char*);
intComName(char*);
intGetCpp();
intGetCom();
intGetData();
floatGetAve();
voidDisplay();
};
voidGrade:
:
PutNo(char*s)
{strcpy(Number,s);}
voidGrade:
:
PutName(char*s)
{strcpy(Name,s);}
voidGrade:
:
PutCpp(intx)
{Cpp=x;
Calc();//输入新数据就要计算平均值
}
voidGrade:
:
PutCom(intx)
{Computer=x;
Calc();//输入新数据就要计算平均值
}
voidGrade:
:
PutData(intx)
{DataBase=x;
Calc();//输入新数据就要计算平均值
}
voidGrade:
:
Calc()
{Average=(Cpp+Computer+DataBase)/3;
}
voidGrade:
:
SetGrade(char*s1,char*s2,intx,inty,intz)
{strcpy(Number,s1);
strcpy(Name,s2);
Cpp=x;
Computer=y;
DataBase=z;
Calc();//输入新数据就要计算平均值
}
intGrade:
:
ComNo(char*s)
{return(!
strcmp(Number,s));}
intGrade:
:
ComName(char*s)
{return(!
strcmp(Name,s));}
intGrade:
:
GetCpp(){returnCpp;}
intGrade:
:
GetCom(){returnComputer;}
intGrade:
:
GetData(){returnDataBase;}
floatGrade:
:
GetAve(){returnAverage;}
voidGrade:
:
Display()
{
cout<<"学号:
"<cout<<"姓名:
"<cout<<"C++程序设计语言的成绩:
"<cout<<"计算机原理的成绩:
"<cout<<"数据库的成绩:
"<cout<<"平均成绩:
"<}
4.2建造集合类实训
4.2.1实训题目和要求
设计一个表示整型数据的集合类,可以对集合中的数据进行添加、删除,可以判断一个整数是否在这个集合里,可以求出集合数据的多少,可以判断集合的空和满,空集合就是没有数据元素,满集合是数据元素已经占满给出的存储单元。
两个集合可以做交运算,就是将两个集合的公共数据组成一个新的集合。
两个集合可以做并运算,就是将两个集合的所有数据组成一个新的集合。
实训目的是通过类实训学会用VC++编写类。
实训要求:
(1)分析集合类的数据属性要求。
(2)分析集合类的操作属性要求。
(3)编制集合类的接口定义。
(4)实现集合类的属性函数。
4.2.2实训参考步骤
设计一个类,首先为类起一个有意义的名字,用集合的英文单词Set作为类名。
接着分析类的数据成员,要实现整型数据的集合类,必须有存放整型数的地方,最方便的是定义一个整型数组,数组名为IntArray[N],最多可以存放N个整数,还要定义一个整型数Last表示已经存放的数据元素的个数。
有趣的是下标小于Last的地方已经存储了数据,Last正好是可以存放新数据的第一个空位置,如图4.1所示。
这里N要设计为常数。
IntArray[N]下标
36
148
57
69
72
81
…
0
1
Last
N-1
图4.1Set类中的数组结构
添加新的数据Append,只要数组没有放满,就直接放到Last位置,再将Last加1。
删除数据Delete,如果要删除图4.1的最后一个81,只要将Last减1就行了,说明原来存放81的位置空了,可以再存放其它数据了,在C++中没有数据的物理删除,只是表明空或非空。
如果要删除中间的数据,就把最后一个数据存入要删除数据的位置,然后将Last减1。
若要删除57得到结果如图4.2所示。
判断一个整数是否在这个集合中IsInSet,由整数与集合中的元素进行逐个比较来实现。
集合空Empty时,Last==0;集合满Full时,Last==N。
两个集合的交运算Intersect,是将两个集合的公共数据组成一个新的集合。
两个集合的并运算Union,是将两个集合的所有数据组成一个新的集合。
Set类还要有一个初始化函数Init,给Last赋初值,就是Last=0。
IntArray[N]下标
36
148
81
69
72
…
0
1
Last
N-1
图4.2图4.1删除57后Set类中的数组结构
下面实现Set类:
先定义常量N。
//先定义常量N
constintN=1024;//假设最多存放1024个元素
//定义类Set
classSet{
intIntArray[N];
intLast;
public:
voidInit();
intAppend(int);
intDelete(int);
intMember(int);
intEmpty();
intFull();
voidIntersect(Set);
voidUnion(Set);
voidDisplay();
};
voidSet:
:
Init(){Last=0;}
intSet:
:
Empty()//判别集合是否空
{
if(Last==0)return1;
return0;
}
intSet:
:
Full()//判别集合是否满
{
if(Last==N)return1;
return0;
}
intSet:
:
Member(intx)//判别整数x是否在集合里
{
inti;
for(i=0;iif(IntArray[i]==x)return1;
return0;
}
intSet:
:
Append(intx)//向集合中添加整数x
{
if(Full())return0;
inti;
for(i=0;iif(Member(x))return1;//集合中已经有x
IntArray[Last]=x;
Last++;
return1;//插入x
}
intSet:
:
Delete(intx)//删除集合中的整数x
{
inti;
for(i=0;iif(IntArray[i]==x)break;
if((iIntArray[i]=IntArray[Last-1];
Last--;
return1;
}
return0;
}
voidSet:
:
Intersect(Sets)//求2个集合的交集
{
inti,j;
for(i=0;ifor(j=0;jif(IntArray[i]==s.IntArray[j])break;
if((jDelete(IntArray[i]);
i--;
}
}
voidSet:
:
Union(Sets)//求2个集合的并集
{
inti;
for(i=0;iAppend(s.IntArray[i]);
}
voidSet:
:
Display()//显示集合中的所有元素
{
inti;
for(i=0;icout<if((i+1)%5==0)cout<}
cout<}
主要成员函数说明:
⑴Append(intx)函数实现向集合中添加整数x。
“if(Full())return0”表示如果集合中存满了数据,就返回0,表示添加失败;for循环语句查找集合中是否已经存放了x,若已经有了x,不用做添加操作就返回1,表示添加成功;否则,IntArray[Last]=x实现添加,并且总元素数加1。
⑵Delete(intx)函数实现删除集合中的整数x。
for循环语句查找集合中存放的x,if语句判断是否找到x,找到就把最后一个数据放入x的位置,并且总元素数减1,返回1。
i>=Last表示没有找到,返回0。
⑶Intersect(Sets)函数实现求2个集合的交集,一个是当前的集合,一个是集合s。
“for(j=0;j⑷Union(Sets)函数实现求2个集合的并集,一个是当前的集合,一个是集合s。
for循环语句将s集合中的每个元素依次插入当前集合中。