![第9章 静态与友元_第1页](http://file4.renrendoc.com/view/6226f92c105d49748e964026002852d4/6226f92c105d49748e964026002852d41.gif)
![第9章 静态与友元_第2页](http://file4.renrendoc.com/view/6226f92c105d49748e964026002852d4/6226f92c105d49748e964026002852d42.gif)
![第9章 静态与友元_第3页](http://file4.renrendoc.com/view/6226f92c105d49748e964026002852d4/6226f92c105d49748e964026002852d43.gif)
![第9章 静态与友元_第4页](http://file4.renrendoc.com/view/6226f92c105d49748e964026002852d4/6226f92c105d49748e964026002852d44.gif)
![第9章 静态与友元_第5页](http://file4.renrendoc.com/view/6226f92c105d49748e964026002852d4/6226f92c105d49748e964026002852d45.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第九章静态与友元
9.1静态
9.2友元
9.3案例实战第一节:静态9.1.静态共享单车、共享汽车、共享充电宝等共享经济产品层出不穷,给大家带来很多方便,节约了社会资源。类的对象数据成员是独立的,不同对象的数据成员各有其值,互不相干。如果要共享某一个数据成员,该如何实现呢?问题9.1.静态C++静态成员作为类的一种成员,可以实现多个对象之间的数据共享,而且使用静态成员还不会破坏信息隐蔽的原则,保证了程序的安全性。静态成员包括静态数据成员和静态成员函数。9.1.1静态数据成员类的普通数据成员在类的每一个对象中都有自己的一个存储空间,可以存储不同的数值。静态数据成员是类数据成员的一种特例,每个类只为静态数据成员分配一个存储空间,它由该类的所有对象共同拥有,从而实现了同一个类不同对象之间的数据共享。静态数据成员具有静态生存期,从程序运行时存在,直到程序运行结束。声明静态数据成员格式:static数据类型
静态数据成员名;9.1.1静态数据成员注意:静态数据成员要求在类内声明,类外初始化。静态数据成员初始化格式:
数据类型类名::静态数据成员名=初始值;静态成员如果没有对其进行初始化,则自动赋初值为0。静态数据成员访问方式:在类外通过类名进行访问,也允许用对象名进行访问。静态数据成员的访问形式:
类名::静态数据成员名;对象名.静态数据成员名注意:静态数据成员受访问权限控制。9.1.1静态数据成员【例如】定义一个矩形类Rectangle,实现计算、显示矩形面积和统计矩形个数的功能。#include<iostream>usingnamespacestd;classRectangle{public: Rectangle(int=0,int=0); voidShow(); intArea();
staticintcount; //声明静态数据成员countprivate: intlength; intwidth;};
intRectangle::count=0; //初始化静态数据成员count9.1.1静态数据成员Rectangle::Rectangle(intl,intw):length(l),width(w){ count++; //静态数据成员count计数}intRectangle::Area(){ return(length*width);}voidRectangle::Show(){ cout<<"length="<<length<<""; cout<<"width="<<width<<""; cout<<"Area="<<Area()<<endl;}9.1.1静态数据成员intmain(){ Rectanglerect1(3,3); rect1.Show();
cout<<"count="<<Rectangle::count<<endl; Rectanglerect2(3,7); rect2.Show(); cout<<"count="<<Rectangle::count<<endl; Rectanglerect3(5,5); rect3.Show();
cout<<"count="<<rect3.count<<endl; return0;}运行结果:length=3width=3Area=9count=1length=3width=7Area=21count=2length=5width=5Area=25count=39.1.2静态成员函数
通常当我们定义类的数据成员时,都会将访问权限定义为私有,同时静态数据成员也受访问权限的控制。如果将静态数据成员定义为私有的,就不能在类外进行访问。
为了解决这个问题,通常会定义对应的公有的静态成员函数来访问私有的静态数据成员。问题9.1.2静态成员函数静态成员函数作用:定义公有静态成员函数来访问私有的静态数据成员。声明静态成员函数的格式:static函数类型静态成员函数名(参数表);定义静态成员函数的格式:
函数类型类名::静态成员函数名(参数表)
{}静态成员函数访问格式:
类名::静态成员函数名(参数表);
9.1.2静态成员函数【例题】定义一个学生Student类,其中包括描述学生信息的学号、姓名、性别和操作系统课程的成绩。需要完成学生信息的输入、显示、计算操作系统课程平均分的功能。classStudent{public:Student(string="",string="",char='f',double=0); voidInput(); voidShow();
staticdoubleAverage();//静态成员函数,计算平均分 ~Student(){}private: stringnum;stringname;charsex; doublescore; //操作系统成绩
staticintcount; //静态数据成员,记录学生人数
staticdoublesum; //静态数据成员,求学生总分};intStudent::count=0; //初始化静态数据成员doubleStudent::sum=0;9.1.2静态成员函数Student::Student(stringn1,stringn2,charch,doubles):num(n1),name(n2),sex(ch),score(s){}voidStudent::Input(){cout<<"num=";cin>>num; cout<<"name=";cin>>name; cout<<"sex=";cin>>sex; cout<<"score=";cin>>score;
count++; //学生计数
sum+=score; //累加成绩}voidStudent::Show(){cout<<num<<setw(N)<<name<<setw(N); if(sex=='f'||sex=='F')cout<<"female"; elsecout<<"male";cout<<setw(N)<<score<<endl;}doubleStudent::Average() //求平均分的静态成员函数{returnsum/count;}9.1.2静态成员函数intmain(){Studentstu[N];intn,i; cout<<"inputstudentnumber:"; cin>>n; for(i=0;i<n;i++) {cout<<"number"<<i+1<<":"<<endl; stu[i].Input(); } cout<<"num"<<setw(N)<<"name"<<setw(N)<<"sex"<<setw(N)<<"score"<<endl;
for(i=0;i<n;i++)stu[i].Show();
cout<<"average="<<Student::Average()<<endl; return0;}9.1.2静态成员函数案例总结:学生人数和成绩总分定义为私有静态数据成员,实现了类对象共有。公有静态成员函数average实现了对私有静态数据成员的访问,即总分除以人数得到平均分。在类的外部,这里就是主函数,直接通过类名作用域限定符调用average函数,间接实现了对私有静态成员count和sum的访问。公有静态成员函数把对私有静态成员的操作实现了封装,进行统一处理,程序的逻辑性更强,安全性更高。9.1.2静态成员函数课堂总结:(1)静态成员受访问权限的控制。(2)静态成员的访问方式有两种:通过类名或通过对象名。(3)静态数据成员的初始化必须在类外,不能通过构造函数进行初始化。(4)静态成员函数的作用就是为了访问私有的静态数据成员,尽量不去访问非静态数据成员。(5)静态成员函数没有this指针,因为它不属于任何一个对象。第二节:友元9.2.1友元函数类具有封装和信息隐蔽的特性,只有类的成员函数才能访问类的私有成员,其他函数无权访问。为提高运行效率,有时确实需要非成员函数能够访问类的私有成员。解决访问类的私有成员的方法:(1)定义公有成员函数访问私有数据成员,通过类外调用公有成员函数达到目的;(2)使用友元机制。友元分为友元函数和友元类。9.2.1友元函数1.将普通函数声明为友元函数声明友元函数时,用关键字friend进行说明,可以访问类的私有成员。普通函数声明为友元函数的格式:friend函数类型友元函数名(参数表);
说明:(1)友元函数为非成员函数,一般在类中进行声明,在类外进行定义;(2)友元函数的声明可以放在类声明中的任何位置,即不受访问权限的控制;(3)友元函数可以通过对象名访问类的所有成员,包括私有成员。9.2.1友元函数【程序举例】定义一个点类Point,并求出两点间的距离#include<iostream>#include<cmath>usingnamespacestd;classPoint{public: Point(int=0,int=0);//带默认值的构造函数 ~Point(){}//析构函数 voidShow();//显示函数
frienddoubleDistance(Pointp1,Pointp2);//声明为友元private: intx,y;};9.2.1友元函数Point::Point(intx1,inty1):x(x1),y(y1){}voidPoint::Show(){cout<<"("<<x<<","<<y<<")"<<endl;}doubleDistance(Pointp1,Pointp2)//求距离
{ returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}intmain(){Pointp1(3,4),p2; p1.Show();p2.Show(); cout<<"Distance:"<<Distance(p1,p2)<<endl; return0;}运行结果:(3,4)(0,0)Distance:59.2.1友元函数2.将成员函数声明为友元函数成员函数声明为友元函数的格式:friend函数类型类名::友元函数名(参数表);如果友元函数是一个类的成员函数,则在定义友元函数时要加上其所在类的类名。访问友元函数时,在友元函数的前面加上自己的对象名即可。如果同一函数需要访问不同类的对象,那么最适用的方法是使它成为这些不同类的友元,关键字friend在函数定义中不能出现。9.2.1友元函数【程序举例】定义一个学生类Student和一个教师类Teacher。在教师类中定义一个能修改学生成绩的成员函数。(1)定义学生类Student。classStudent{public: Student(string="",string="",double=0); ~Student(){} voidShow();private: stringnum;stringname;doublescore;};Student::Student(stringn1,stringn2,doubles):num(n1),name(n2),score(s){}voidStudent::Show(){cout<<setw(8)<<"num"<<setw(8)<<"name"<<setw(8)<<"score"<<endl; cout<<setw(8)<<num<<setw(8)<<name<<setw(8)<<score<<endl;}9.2.1友元函数(2)定义教师类Teacher,并在主函数中定义对象进行测试。
#include<iostream>#include<string>#include<iomanip>usingnamespacestd;classTeacher{public: Teacher(string="",string=""); ~Teacher(){} voidShow_Teacher();private: stringnum;stringname;};Teacher::Teacher(stringn1,stringn2):num(n1),name(n2){}voidTeacher::Show_Teacher(){cout<<setw(8)<<"num"<<setw(8)<<"name"<<endl; cout<<setw(8)<<num<<setw(8)<<name<<endl;}9.2.1友元函数(3)在教师类中添加修改学生成绩的成员函数。
#include<iostream>#include<string>#include<iomanip>usingnamespacestd;classStudent;//类的提前声明classTeacher{public:
voidSetScore(Student&,double);//修改指定学生成绩 //希望能更新数据,所以学生对象必须定义为引用或者指针。
……};classStudent{……
friendvoidTeacher::SetScore(Student&stu,doubles);//声明为友元函数};voidTeacher::SetScore(Student&stu,doubles)//修改指定学生成绩{
stu.score=s;}//因为是友元函数,可以直接引用私有数据成员stu.score9.2.1友元函数需要说明的几点:(1)关于提前声明:
Teacher类中声明的成员函数SetScore(Student&,double)第一个形参是Student类对象的引用,所以要在Teacher类前加上类Student的提前声明。(2)关于成员函数SetScore(Student&,double):
成员函数的形参中必须给出明确的Student类对象,并更新原有的成绩。所以,将形参定义为引用或指针。(3)在Teacher类的修改成绩的成员函数SetScore(Student&,double)中,访问到了Student类的私有数据成员score,所以将它声明为Student类的友元函数。9.2.2友元类3.友元类C++中,可将整个类声明为另一个类的友元,称为友元类。友元类的声明格式:friendclass友元类名;说明:(1)友元类的声明同样可以在类声明中的任何位置;(2)友元类的所有成员函数将都成为友元函数。9.2.2友元类【程序举例】定义一个学生类Student和一个教师类Teacher。在教师类中定义一个能修改学生成绩的成员函数。#include<iostream>#include<string>#include<iomanip>usingnamespacestd;classStudent;//类的提前声明classTeacher{public: Teacher(string="",string=""); ~Teacher(){} voidShow_Teacher(); voidSetScore(Student&,double);//修改指定学生成绩private: stringnum; stringname;};9.2.2友元类classStudent{public: Student(string="",string="",double=0); ~Student(){} voidShow_Student();
friendclassTeacher;//声明类Teacher为友元类private: stringnum; stringname; doublescore;};voidTeacher::SetScore(Student&stu,doubles)//修改指定学生成绩{
stu.score=s;//直接引用私有学生对象中的私有数据}9.2.2友元类需要注意:(1)友元关系具有单向性。如果声明类A是类B的友元,则类A的所有成员
函数都将变成友元函数,都可以访问类B的所有成员,但类B的成员函数却不能访问类A的私有和保护成员。(2)友元关系不具有传递性。如果类A是类B的友元,类B是类C的友元,
类C和类A之间如果没有声明,就没有任何友元关系,不能进行数据共享。(3)友元的提出方便了程序的编写,但是却破坏了数据的封装和隐蔽,应该尽量减少友元的使用。第三节:案例实战9.3.1案例实战酒店管理系统,要求定义一个酒店类,客人类,客人类为酒店类的友元类,可以直接获取酒店基本信息,实现客人的入住添加、查找、修改、删除和浏览功能。9.3.1案例实战案例分析(1)定义客人类。通常客人信息包括:编号,姓名,房间号和费用以及统计酒店总收入、总人数。常用的基本操作包括:初始化访客入住信息,获取访客编号,姓名,房间号,房费,酒店总人数,总费用信息,增加总人数费用,减少总人数和显示房客信息。总人数、总费用声明为静态成员,修改总人数、费用,获取总人数、总费用为静态函数。(2)定义酒店类。酒店信息包括:酒店名称和房间类别,基本操作初始化酒店名称,声明客人类为酒店的友元类,客人类的成员函数可以直接访问酒店的名称和房间类别信息。(3)定义管理函数。定义管理函数,如用户界面函数实现主界面,输入操作的功能编号;检测客人e的房间号状态函数,检测客人e的编号状态,添加房客,删除房客信息,查找房客和更新房客信息操作。(4)定义主程序。初始化酒店对象,客人对象,循环调用用户界面函数,根据输入编号调用各种管理函数。程序代码#include<iostream>#include<string>#include<iomanip>#defineM100//房客最大人数usingnamespacestd;//**********客人类**********classHotal;//前置声明classGuest{private: intNum;//客人编号; stringName;//姓名; intRoom;//房间号; intfee;//费用; staticdoubleSum;//总收入; staticintCount;//总人数;public: Guest(int=0,string="",int=0,int=0);//初始化访客入住信息:编号、姓名、房间号和费用 staticdoubleSumfee();
//静态成员函数,计算总收入; staticintpep();
//静态成员函数,计算总人数; voidshow(Hotalh);
//显示房客信息 voidsetName();
//设置姓名 voidsetFee();
//设置房费 intgetNum(){returnNum;}
//获取客人编号 stringgetName(){returnName;}
//获取客人姓名 intgetRoom(){returnRoom;}
//获取房间号 intgetFee(){returnfee;}//获取房费 voidtotal_add();
//修改静态成员:总人数,总费用 voidtotal_sub();
//修改静态成员:总人数,总费用};//初始化静态数据成员intGuest::Count=0;doubleGuest::Sum=0;//***********酒店类*********classHota{public: Hotal(string="");private: stringHotalName;//酒店名称 stringRoomType[3];//房间类别 friendclassGuest;//定义友元类};//**********定义各种管理函数**********intmenu();//用户界面函数intVaild_room(Guest*e,introom);//检测客人e的房间号状态intVaild_Num(Guest*e,intnum);//检测客人e的编号状态voidaddGuest(Guest*e);//添加房客voiddeleteGuest(Guest*e,Hotalh);//删除房客信息Guest&searchGuest(Guest*e);//查找房客voidupdateGuest(Guest*e);//更新房客信息//主程序intmain(){ Guestg[M]; Hotalh("夏季假日酒店"); while(1){ switch(menu()){ case1:addGuest(g); break; case2:{ Guestg1=searchGuest(g); g1.show(h); break; } case3:updateGuest(g); break; case4:deleteGuest(g,h); break; case5:cout<<"总人数:"<<Guest::pep()<<endl; break; case6:cout<<"总费用:"<<Guest::Sumfee()<<endl; break; case0: return0; default: cout<<"输出有误,请重新选择!"<<endl; } } return0;}//酒店类的实现--略//客人类的实现--略//管理类函数的实现-部分intmenu()//用户界面函数{ cout<<"**************************************************"<<endl; cout<<"**"<<endl; cout<<"*欢迎使用房客信息管理系统*\n";cout<<"**"<<endl; cout<<"*1.添加房客信息2.查询房客信息*"<<endl; cout<<"*3.修改房客信息4.删除房客信息*"<<endl; cout<<"*5.显示所有房客信息6.计算总收入*"<<endl; cout<<"*0.退出系统
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度新能源电站安装工程一切险保险合同
- 2025年度绿色建筑项目脚手架施工合同范本
- 2025年度借款合同强制执行公证程序标准文本
- 2025年度建筑装修工程项目管理与咨询合同
- 2025年光伏产业园区规划设计技术咨询合同
- 2025年仓储货物交易合同
- 2025年个人和公司的合作合同(4篇)
- 2025年个人住房贷款借款合同经典版(2篇)
- 2025年人员招聘合同解除协议
- 2025外汇质押人民币借款合同范本专业版范文
- 《造血干细胞移植护理》课件
- 课题申报参考:全龄友好视角下的社区语言景观评估及空间优化研究
- 中央2025年公安部部分直属事业单位招聘84人笔试历年参考题库附带答案详解
- 五年级下册语文四大名著常考知识点
- 2025年1月日历表(含农历-周数-方便记事备忘)
- 2024年同等学力人员申请硕士学位英语试卷与参考答案
- 临床用血管理培训
- 工业自动化生产线操作手册
- 《走进神奇》说课稿
- 2024年内蒙古中考语文试卷五套合卷附答案
- 五年级下册语文教案 学习双重否定句 部编版
评论
0/150
提交评论