实验三类与对象㈢——静态成员、常量成员、友元、对象成员
一、实验目的
1.理解静态数据成员、静态成员函数的作用,熟悉其应用;
2.理解常量对象、常量数据成员、常量成员函数作用,熟悉相互关系及应用;
3.熟悉友元函数、友元类的定义及应用;
4.熟悉对象成员(容器类)的应用;
5.进一步熟悉类与对象的应用及编程。
二、实验学时
课内实验:2课时课外练习:2课时
三本实验涉及的新知识
㈠静态成员
静态成员分为静态数据成员及静态成员函数。
1.静态数据成员
⑴静态数据成员的定义(类中定义)
格式:
static 类型数据成员名表;
⑵静态数据成员的作用
静态数据成员在一个类中只有一个拷贝,属于一个类(或者说属于类的第一个对象),所有对象都共享静态成员。
静态数据成员是连接各个对象的桥梁,可用来取代全局变量,主要用于各个对象都共享的公用数据,如:总数的统计、平均数等。
⑶说明
①静态数据成员可以说明为公有成员、私有成员或保护成员,但一般不说明为公有成员;
②静态数据成员同其它数据成员一样,不能在类中进行初始化(不分配内存空间);
③静态数据成员由于属于类(不依赖任何对象),应在程序开始运行时即生成,必须在任何函数之外进行初始化操作;
格式:
类型类名::静态数据成员=初值;
④使用静态数据成员取代全局变量,使数据更为安全;
⑤当在类中需要共享某一数据成员时通常定义为静态数据成员;
⑥静态数据成员与静态对象是两个完全不同的概念,前者(静态数据成员)是在类中定义的,是类的所有对象共享的数据成员,而后者(静态对象)是指对象存储在静态存储区。
2.静态成员函数
⑴静态成员函数的定义
静态成员函数是在定义类的成员函数时,在成员函数名前加上static。
⑵静态成员函数的调用方法
①用类名调用
格式:
类名::静态成员函数名(实参表);
②用对象调用
格式:
对象名.静态成员函数名(实参表);
⑶说明
①静态成员函数可以在类内部定义(必须加上static),也可在类外定义,即在类体内声明,在类体外定义,定义时与普通成员函数相同;
②静态成员函数无this指针(this指针属于某一对象,静态成员属于一个类),只能访问静态数据成员,不能访问普通数据成员,因此静态成员函数专门用来访问静态数据成员;
③当在类中定义有静态数据成员时,通常应定义静态成员函数来访问静态数据成员。
㈡常量成员函数、常量数据成员及常量对象
在C++中可以用const定义常量对象(也称为常对象)、常量成员函数(也称为常成员函数)、常量数据成员(也称为常数据成员)。
1.常量成员函数的定义
⑴在类中定义:
返回类型成员函数名(参数表) const
{ 函数体}
⑵在类外定义
类中声明:
返回类型成员函数名(参数表) const ;
类外定义:
返回类型类名::成员函数名(参数表) const
{ 函数体}
2.常量数据成员的定义
定义格式:
const 数据类型成员名
或:
数据类型const 成员名
3.常量对象的定义
定义格式:
类名const 对象名表;
或:
const 类名对象名表
4.说明
⑴常量对象只能在定义时初始化,其数据成员的值不能改变。
⑵常量对象只能调用常量成员函数,不能调用普通成员函数;而普通对象既可调用普通成员函数,也可以调用常量成员函数。
⑶普通成员函数可以访问本类的常量成员函数,而常量成员函数不能访问本类的普通成员函数。
⑷常量成员函数与普通成员函数同名时,构成函数的重载,其参数类型和个数可以相同,而用const加以区分。
⑸常量数据成员必须在构造函数中通过初始化列表进行初始化,初始化后值不能改变。
⑹常量数据成员及成员函数隶属于某一对象(与静态数据成员的差异)。
㈢友元
1.友元的概念
在C++中提供了一种类以外的函数访问类的私有成员、保护成员的方法,即将这些函数定义
为类的友元。
2.友元的种类及应用
⑴友元函数
定义方法:在类中进行声明时,在声明的前面加上friend。
说明:
①友元函数不是类的成员函数,除非确因成员函数使用频繁,需要提高程序的执行效率而定义为友元函数外,一般不要定义。
②友元函数可以访问对象的私有成员和保护成员,只是在类中声明时加上friend,但它不是成员函数,定义时不能在函数名前加上“类名::”。
③友元函数无this指针,一般至少应带有一个入口参数,通过入口参数传递的对象名来引用该对象的成员。
④友元函数主要用于运算符的重载。
⑵友元成员
友元成员是指一个类的成员函数可以是另一个类的友友元函数,这样就可以通过一个类的成员函数访问另一个类的私有成员或保护成员。
说明:
①一个类的成员函数要作为另一个类的友元函数时,必须先定义这个类。
②由于友元函数所在的类名先于类的定义出现,应先声明。
⑶友元类
友元类是指一个类可以作为另一个类的友元,这样友元类的所有成员函数均可以访问另一个类中的成员。
㈣容器类
1.容器类的概念
在定义一个类的数据成员时,除可以是基本数据成员外,还可以是其它类的对象,称为对象成员。含有对象成员的类称为容器类。
2.容器类构造函数
⑴格式
类名(形参表):成员名1(参数表1),… , 成员名n(参数表n)
⑵说明:
①容器类中至少应有一个构造函数,以通过参数表为成员对象赋初值。
②创建容器类对象时,先执行对象成员所属类的构造函数,再执行容器类构造函数的函数体。
③释放容器类对象时,先调用容器类的析构函数,再调用对象成员所属类的析构函数。
3.用容器类对象调用对象成员所属类的公有成员函数
格式:
容器类对象成员名.对象成员所属类名::成员函数名(实参表);
四、实验内容
㈠验证及认知实验
按要求调试下列程序并回答相关问题。
程序1(exp_301.cpp)
#include
class counter
{ private:
static int count; //count为静态数据成员
char ch; //普通数据成员
public:
counter(char c) //构造函数
{ this->count ++;ch=c;}
void print_counter(void)
{cout< ~counter(void) {count--;} }; int counter::count=100; //静态数据成员赋初值 void main(void) { counter c1('A'); c1.print_counter(); cout< counter c2('B'); c1.print_counter(); c2.print_counter(); cout< counter c3('C'); c1.print_counter(); c2.print_counter(); c3.print_counter(); } 问题: ⑴运行该程序的输出结果为 ⑵由输出结果可知,静态成员属于,在类中只有拷贝。 ⑶程序中的“int counter::count=100;”的作用是,如果将其放在main()函数中,重新编译程序,会出现,其原因是。 程序2 //头文件“hhpoint.h”中point类的定义: class point { private: float x,y; public: point(void) //无参构造函数 {x=0;y=0;} point(float a,float b) //构造函数重载 {x=a ; y=b; } point(const point &ob) //拷贝构造函数 {x=ob.x;y=ob.y;} void set_point(float a,float b); float read_x(void); float read_y(void); void move(float a,float b); void print(void); }; void point::set_point(float a,float b) {x=a ; y=b; } float point::read_x(void) { return x;} float point::read_y(void) { return y;} void point::move (float a,float b) { x+=a;y+=b;} void point::print(void) { cout<<"x="< //#include"point.h" //(2) void main(void) { const point center(100,100); point p(20,40); cout<<"Before moving:"< cout<<"p: "<<"x="< cout<<" y="< cout<<"center: "<<"x="< cout<<" y="< // p.move(10,20); //(3) // cout<<"After moving: "< // cout<<"p: "<<"x="< // cout<<" y="< // center.move(20,20); //(7) } 问题: ⑷编译程序,会出现,其出错原因是 。 ⑸将程序中(1)改为注释,再将(2)行首的注释去掉,再编译运行程序,程序的输出结果为: ⑹将程序中(3)—(6)行首的注释去掉,程序的输出结果为: ⑺将程序中的(7)行首的注释去掉,编译程序时无错,而运行程序时会出现错误,其原因是。 程序3(exp_303.cpp) #include #include class girl { private: char *name; int age; public: girl(char *na,int n) { name=new char[strlen(na)+1]; strcpy(name,na); age=n; } ~girl(void) {delete name;} //释放new分配的内存 char *get_name(void) {return name;} int get_age(void) {return age;} void print_girl(void); }; void girl::print_girl(void) { cout<<"姓名:"< cout<<" 年龄:"< } void disp(girl &g) { cout<<"姓名:"< cout<<" 年龄:"< } void main(void) { girl g1("李小丫",12),g2("王永兰",15),g3("赵梦美",13); cout<<"姓名:"< cout<<" 年龄:"< g2.print_girl(); disp(g3); } 问题: ⑻编译程序出错的原因是。 ⑼在girl类中加上“friend void disp(girl &g);”重新编译、运行程序,其输出结果为: 其中,“friend void disp(girl &g);”表示函数disp( )为girl类的。 ㈡知识应用实验 1.分析下列程序,写出程序的输出结果,再上机运行程序验证其正确性,如果不正确,请认真分析出错原因。 程序4(exp_304.cpp) #include class simple { private : static int v1,v2,v3; public: simple(int x=0,int y=0) {v1=x;v2=y;} static void sum(void) {v3=v2+v1;} int get_v3(void) {return v3;} }; int simple::v1=0; int simple::v2=0; int simple::v3=0; void main(void) { simple ob1(5,10); ob1.sum(); cout<<"(1): "< simple::sum(); cout<<"(2): "< 程序5(exp_305.cpp) #include #include 程序的实际输出结果是: 你分析的程序输出结果是: class boy;//类boy 的声明; class girl { private: char *name; int age; public: girl(char *na,int n) { name=new char[strlen(na)+1]; strcpy(name,na); age=n; } ~girl(void) {delete name;} //释放new 分配的内存 friend void disp(girl &g,boy &b);//声明disp 为girl 类友元函数 }; class boy { private: char *name; int age; public: boy(char *na,int n) { name=new char[strlen(na)+1]; strcpy(name,na); age=n; } ~boy(void) {delete name;} //释放new 分配的内存 friend void disp(girl &g,boy &b);//声明disp 为boy 类友元函数 }; void disp(girl &g,boy &b) //定义友元函数:不是类的成员不需要作用域运算符 { cout<<"女孩姓名:"< cout<<" 年龄:"< cout<<"男孩姓名:"< cout<<" 年龄:"< } void main(void) { girl g1("李小丫",12);boy b1("张海兵",15); disp(g1,b1);//调用友元函数:与普通函数调用相同 } 程序6 //头文件“hdate.h ”的内容://定义“date ”类 class date 程序的实际输出结果是: 你分析的程序输出结果是: { private: int year,month,day; public: date(void) { year=1980;month=1;day=1;} date(int y,int m,int d) 程序的实际输出结果是:{ year=y;month=m;day=d;} int get_year(void) {return year;} int get_month(void) {return month;} int get_day(void) {return day;} }; //头文件“hperson.h”的内容:定义“person”类 #include #include"hdate.h" class person { private: char *name; char sex[2]; date birthday; public: person(char *na,char *s,int y,int m,int d):birthday(y,m,d) { name=new char[strlen(na)+1]; strcpy(name,na); strcpy(sex,s); } char *get_name(void){return name;} char *get_sex(void){return sex;} int get_year(void){return birthday.get_year();} int get_month(void){return birthday.get_month();} int get_day(void){return birthday.get_day();} ~ person(void){delete []name;} void print(void); }; void person::print(void) { cout<<"姓名:"< cout<<"性别:"< cout<<"出生日期:"< cout< cout< } //测试程序“exp_306.cpp” #include #include"hperson.h" void main(void) { person ps1("张小三","男",1985,12,15); person ps2("李小丫","女",1986,3,9); ps1.print(); cout< ps2.print(); } 2.完善、调试通过下列程序,并按所要求回答问题。程序7(exp_307.cpp) #include #include class boy;//类boy的声明; class girl { private: char *name; int age; public: girl(char *na,int n) { name=new char[strlen(na)+1]; strcpy(name,na); age=n; } ~girl(void) {delete name;} //释放new分配的内存 void disp( (1) ); }; class boy { private: char *name; int age; (2) ; //声明girl是boy的友元类public: boy(char *na,int n) { name=new char[strlen(na)+1]; strcpy(name,na); age=n; } ~boy(void) {delete name;} //释放new分配的内存 }; void girl::disp( (1) ) { cout<<"女孩姓名:"< cout<<" 年龄:"< cout<<"男孩姓名:"< cout<<" 年龄:"< } void main(void) { girl g1("李小丫",12);boy b1("张海兵",15); g1.disp(b1); } ㈢程序设计实验 编写程序,定义一个平面点“Point”类及计算两点之间距离“Distance”类,将“Distance”类定义为“Point”类的友元类;并在main()中计算任意两点的距离(保存在exp_308.cpp中)。 四、实验收获与创新 1.通过“实验一”至“实验三”,谈谈你对面向对象程序设计“数据封装与隐藏”的认识。 2.自已拟定一个解决实际问题的题目,综合应用“实验一”至“实验三”的知识,编写程序并调试通过。 实验三类、对象基础知识 一、实验目的 1、熟练掌握类、对象的的概念以及对事物的抽象。 2、熟练掌握成员、方法的概念以及构造方法的概念。 3、熟练掌握封装性,多态性的概念 4、理解面向对象的程序设计方法。 二、实验内容与要求 1运行下面的程序,理解面向对象的程序设计方法的基本概念。 class value { public int x,y; public value(int a,int b) { x=a; y=b; } } public class Ch31 { public static void main(String args[]) { int total; value num=new value(24,65); total=num.x+num.y; System.out.println("add="+total); } } 2、定义一个类实现银行帐户的概念,包括的变量有"帐号"和"存款余额",包括的方法有"存款"、"取款"、"查询余额"和”显示帐号”,。定义主类,创建帐户类的对象,并完成相应操作。提示:关键代码如下: public int getleftmoney(){ return leftmoney; } public void savemoney(double money){ leftmoney+=money; } public void getmoney(double money){ if(money<=leftmoney) leftmoney-=money; else System.out.println("只能取:"+leftmoney); } … 实验3 类和对象的创建与使用 一、实验目的 1、掌握类的定义和对象的创建; 2、掌握构造方法的作用、格式及重载; 3、掌握修饰词对成员存取权限的限制。 4、掌握实例成员、类成员的定义和使用方法。 二、实验内容 1、定义储蓄账户类,并创建对象模拟银行基本操作。 2、两游戏角色决斗。给定二个不同的角色,判定交手的胜负关系。(选做) 3、设计学生类、学校类、录取类,根据学生成绩和学校分数线,判断是否录取。 三、实验步骤 说明:请将第1,3题代码写入实验报告实验步骤处。 1、模拟银行账户功能。 编写程序,模拟银行账户功能。要求如下: 属性:账号、姓名、地址、存款余额、最小余额。 方法:存款、取款、查询。 根据用户操作显示储户相关信息。 如存款操作后,显示储户原有余额、今日存款数额及最终存款余额。 取款时,若取款成功,显示信息提示;若最后余额小于最小余额,拒绝取款,并显示信息提示。具体显示信息可据方便性原则自拟。 public class AccountOperation { public static void main(String [] args) { Account account1=new Account("650101","柳眉","天河学院",800.00); Account account2=new Account("650102","郑杰","天河学院",200.00); account1.transfer(account1,account2,300.0); account1.deposit(300.5); account1.withdraw(200); account1.withdraw(300); account1.query(); System.out.println(account1.toString()); //System.out.println(https://www.wendangku.net/doc/e016107522.html,); error!! } } class Account { private String account; private String name; private String address; private double balance; 实验04 类与对象(6学时) (第4章类与对象) 一、实验目的 二、实验任务 4_1 声明一个CPU类。 包含等级(rank)、频率(frequency)、电压(voltage)等属性,有两个公有成员函数run、stop。其中,rank为枚举类型CPU_Rank,声明为enum CPU_Rank{ P1=1, P2, P3, P4, P5, P6, P7 }; frequency为单位是MHz的整型数,voltage为浮点型的电压值。观察构造函数和析构函数的调用顺序。 4_2 声明一个简单的Computer类。 有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等,有两个公有成员函数run和stop。cpu为CPU类的一个对象,ram为RAM类的一个对象,cdrom为CDROM类的一个对象,声明并实现这个类。 4_3 声明一个表示时间的结构体。 可以精确表示年、月、日、小时、分、秒;提示用户输入年、月、日、小时、分、秒的值,然后完整地显示出来。 4_4(习题4-10)设计一个用于人事管理的People(人员)类。 考虑到通用性,这里只抽象出所有类型人员都具有的属性:number(编号),sex(性别)、birthday(出生日期)、id(身份证号)等。其中“出生日期”声明为一个“日期”类内嵌子对象。用成员函数实现人员信息的录入和显示。要求包括:构造函数和析构函数、内联成员函数、组合。 三、实验步骤 1.(验证)声明一个CPU类,观察构造函数和析构函数的调用顺序。 首先声明枚举类型CPU_Rank,例如enum CPU_Rank{ P1=1, P2, P3, P4, P5, P6, P7 },再声明CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等私有数据成员,声明成员函数run和stop,用来输出提示信息,在构造函数和析构函数中也可以输出提示顺序。在主程序中声明一个CPU的对象,调用其成员函数,观察类对象的构造与析构顺序,以及成员函数的调用。程序名:。(程序见步骤2) ★程序的运行结果: 2.(示例)调试程序文件。 使用调试功能观察程序的运行流程,跟踪观察类的构造函数、析构函数、成员函数的执行顺序。参考程序如下: 操作)调试操作步骤如下: (1)单击“调试 | 逐语句”命令,系统进行单步执行状态,程序开始运行,一个DOS 窗口出现,此时Visual Studio中光标停在main()函数的入口处。 实验报告_实验3 类的定义、对象的建立与使用(学 生学号_姓名) 实验目的: 1、理解C++中class与struct的区别; 2、掌握类的定义以及成员函数的定义方法; 3、掌握对象的定义和对象成员的访问方式; 4、熟悉this指针的基本用法。 实验内容 二、((基础题)请按照下列要求定义一个Clock时钟类,并创建对象,再调用相应方法: 程序代码: //日期类的应用 #include int second; }; // 类定义体的结束 //类实现部分 void Clock::setTime(int h, int m, int s) { hour = h; minute = m; second = s; } void Clock::showTime() { cout << "设置时间为" << hour <<":"<< minute <<":"<< second << endl; } int main() { Clock now; now.setTime(8,30, 0); now.showTime(); return 0; } 三、(基础题)请按要求,编写程序(请将类的定义、成员函数的实现、类的使用分开): rect.h代码: #include实验三 类、对象基础知识
实验3 类和对象
C++语言程序设计实验答案_类与对象
实验3 类的定义、对象的建立与使用
C++实验二类与对象(附答案)