面向对象编程技术第五章_第1页
面向对象编程技术第五章_第2页
面向对象编程技术第五章_第3页
面向对象编程技术第五章_第4页
面向对象编程技术第五章_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

面向对象编程技术第五章第1页,共60页,2023年,2月20日,星期四程序、软件中存在大量的实体对象如何解决由此产生数据访问控制问题:如作用域;对象的生命周期;数据共享等等提出问题:第2页,共60页,2023年,2月20日,星期四本章主要内容作用域与可见性对象的生存期数据与函数静态成员友元共享数据的保护编译预处理命令多文件结构和工程数据访问数据共享程序组织第3页,共60页,2023年,2月20日,星期四

数据访问-作用域作用域与可见性的含义。作用域:指标示符在源文件中的有效作用范围可见性:指标识符是否可以引用的问题。

作用域分类函数原型作用域块作用域:搞清块的含义,块是由{}界定的相对独立一段程序空间类作用域:文件作用域:联系与区别第4页,共60页,2023年,2月20日,星期四数据访问-可见性可见性是从对标识符的引用的角度来谈的概念可见性表示从内层作用域向外层作用域“看”时能看见什么。如果标识在某处可见,则就可以在该处引用此标识符。第5页,共60页,2023年,2月20日,星期四数据访问-可见性注意:标识符应声明在先,引用在后。在同一作用域中,不能声明同名的标识符。如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则该标识符在内层可见。对于两个嵌套的作用域,如在内层作用域内声明了与外层作用域中同名的标识符,则外层作用域的标识符在内层不可见。强龙不压地头蛇原则第6页,共60页,2023年,2月20日,星期四#include<iostream.h>inti;//文件作用域intmain(){i=5;{inti;//块作用域

i=7;cout<<"i="<<i<<endl;//输出7}

cout<<"i="<<i;//输出5

return0;}例5.1返回第7页,共60页,2023年,2月20日,星期四函数原形的作用域函数原型中的参数,其作用域始于

"(",结束于")"。例如,设有下列原型声明:doubleArea(doubleradius);doubleArea(double);radius的作用域仅在于此,不能用于程序正文其它地方,因而可有可无。doublearea(doubler){return3.14*r*r;}返回与声明部分的名称可以不同第8页,共60页,2023年,2月20日,星期四块作用域在块中声明的标识符,其作用域自声明处起,限于块中,例如:voidfun(inta){intb(a);cin>>b;if(b>0){staticintc;......}}c的作用域b的作用域什么是块:简言之,{……}返回注意:块内定义的静态变量,具有”文件作用域”第9页,共60页,2023年,2月20日,星期四类作用域类作用域作用于特定的成员名,类及其对象有特殊的访问和作用域规则设类X,X的对象x,成员M,X的函数成员f如f没有新定义同名标识符M,则在f可以访问M可以这样访问:

X::M(大写x);x.M(小写x)

ptr->M(ptr为指向对象x的指针)下页例子第10页,共60页,2023年,2月20日,星期四类作用域classA{public:intb;Staticvoidprt(){Cout<<“test”;Cout<<“b=“<<b<<<endl;…}}可以这样访问Aa;a.b=5;a.prt();A::prt();//如果staticprt()则正确可以的

Aa;a::prt();A.b=12;?返回第11页,共60页,2023年,2月20日,星期四文件作用域在main()之外,且不在前三者作用域范围内的数据具有文件作用域inti,j;……voidmain(){……}请看下页第12页,共60页,2023年,2月20日,星期四准确理解作用域整体视图P123块作用域类作用域文件作用域问题:1.这种包含关系什么时候成立?

2.类作用域一定包含块作用域吗?例?返回第13页,共60页,2023年,2月20日,星期四main(){……{classpart_cla{public:inta;…voidprt(){…}};}{part_clapc;//出错!此时类的作用域不包含块作用域}}返回第14页,共60页,2023年,2月20日,星期四数据访问-对象的生存期对象从产生到结束的这段时间就是它的生存期。在对象生存期内,对象将保持它的值,直到被更新为止。P124静态生存期动态生存期返回第15页,共60页,2023年,2月20日,星期四静态生存期定义:生存期与程序的运行期相同,称为静态生存期在文件作用域中声明的对象具有这种生存期。在函数内部声明静态生存期对象,用关键字static声明的对象。两种静态生存期示例第16页,共60页,2023年,2月20日,星期四#include<iostream.h>inti=5;//文件作用域voidout();voidmain(){cout<<"i="<<i<<endl; out(); out();}voidout(){staticct;++ct;cout<<"ct="<<ct<<endl;}注意:i,ct具有静态生存期例:返回第17页,共60页,2023年,2月20日,星期四动态生存期定义:块作用域中声明的对象是动态生存期的对象(习惯称局部生存期对象)。开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。示例什么是作用域?第18页,共60页,2023年,2月20日,星期四#include<iostream.h>voidfun();voidmain(){fun();fun();}voidfun(){staticinta=1;inti=5;a++;i++;cout<<"i="<<i<<",a="<<a<<endl;}运行结果:i=6,a=2i=6,a=3i是动态生存期a是静态生存期例第19页,共60页,2023年,2月20日,星期四注意:静态生存期与程序的生成期相同,一经创建,便贯穿始终。

静态生存期有局部和全局两种定义方式动态生存期指临时创建,临时使用,动态内存分配变量的生存期与可见性的讨论可见一定生存,但生存未必可见返回联系作用域第20页,共60页,2023年,2月20日,星期四数据访问-数据与函数数据存储在局部对象中,通过参数传递实现共享——函数间的参数传递。数据存储在全局对象中。将数据和使用数据的函数封装在类中。数据、代码结合方式三种基本方式第21页,共60页,2023年,2月20日,星期四voidfunc1(intx){inty;y=x…(1)…intxvoidmain(){……}classA{public:intx;…private:…}(2)返回(3)第22页,共60页,2023年,2月20日,星期四数据访问-静态成员为了解决同类中不同对象的间的数据、函数(代码)共享问题。静态成员的提出:包括静态数据成员静态函数成员如何定义第23页,共60页,2023年,2月20日,星期四数据访问-静态成员静态数据成员用关键字static声明同类的所有对象维护该成员的同一个拷贝必须在类外定义和初始化,用::域运算符来指明所属的类。静态函数成员第24页,共60页,2023年,2月20日,星期四数据访问-静态成员静态函数成员用关键字static声明类外代码可以使用类名和域操作符来调用静态成员函数。静态成员函数只能引用属于该类的静态数据成员或静态成员函数。访问非静态数据成员,必须通过本类的对象来实现。为什么?下页例子第25页,共60页,2023年,2月20日,星期四例子:classa{public:staticintx;staticprt(){cout<<“x=“<<x;};inta::x=0;//对静态成员初始化main(){aa1;a::x=12;a::prt();…a1.x=15;a1.prt();}通过类访问静态成员通过对象访问静态成员第26页,共60页,2023年,2月20日,星期四注意:静态数据成员要在文件作用域中使用类名做限制性初始化。静态数据成员的访问方式:

类名::静态数据成员或对象名.静态数据成员

(与书上的叙述相悖)静态函数成员的访问方式:

类名::静态数据成员或对象名.静态函数数成员

第27页,共60页,2023年,2月20日,星期四注意:静态函数成员的访问对象:

静态数据成员、静态函数成员不能访问非静态数据成员静态成员函数可以直接通过类名::函数名的方式访问静态数据成员,对非静态数据成员只能通过对象名来访问。参考教材P132你明白吗?看实例下页例子第28页,共60页,2023年,2月20日,星期四ClassA{Public:Staticvoidf(Aa);Private:intx;};VoidA::f(Aa){//cout<<x;错误cout<<a.x;//正确}返回原因是,静态函数成员可以通过类名访问,而此时非静态数据成员没有存储空间第29页,共60页,2023年,2月20日,星期四补充:关于静态成员的访问属性静态成员一般设成public访问属性,否则不能以对象方式或者类名::静态成员名的方式访问设成public静态成员访问属性后,可以用对象名和类名::方式访问第30页,共60页,2023年,2月20日,星期四例子:classA{public:staticvoidshow(){cout<<"inclassA\""<<endl; }staticintstkk;//可以用对象名访问活着类名::成员名形式访问protected: //staticintstkk;类外:不予许对象名访问或者类名::成员名形式访问private://staticintstkk;不予许对象名访问或者类名::成员名形式访问};intA::stkk=9;voidmain(){Aa;a.stkk=99;cout<<a.stkk<<endl;cout<<A::stkk<<endl;a.show();A::show();}第31页,共60页,2023年,2月20日,星期四数据共享-友元设计思想:

友元,包括友元函数和友元类,是类和对象向其它类与对象开放本类、对象的的私有、保护成员的有效途径。B(A的友元)类AfriendB…Privateorprotect:……第32页,共60页,2023年,2月20日,星期四数据共享-友元函数ClassA{public:…friend函数B声明…}定义格式:函数B定义{…}第33页,共60页,2023年,2月20日,星期四例:简单友元函数classA{public: A(inti){x=i;} friendvoidacc(A&a);//可以不用引用private: intx;};voidacc(A&a)//可以不用引用,如Aa{cout<<"thexinAis:"<<a.x<<endl;a.x=99;cout<<"thexinAis:"<<a.x<<endl;}intmain(){Aa(9);cout<<a.x<<endl;a.x=99;acc(a);return0;}第34页,共60页,2023年,2月20日,星期四例5-6使用友元函数计算两点距离(P135)classPoint //Point类声明{public: //外部接口

Point(intxx=0,intyy=0){X=xx;Y=yy;} intGetX(){returnX;} intGetY(){returnY;} friendfloatfDist(Pointa,Point&b);private: //私有数据成员

intX,Y;};第35页,共60页,2023年,2月20日,星期四doublefDist(Point&a,Point&b){doubledx=a.X-b.X;doubledy=a.Y-b.Y;returnsqrt(dx*dx+dy*dy);}intmain(){Pointp1(3.0,5.0),p2(4.0,6.0);doubled=Distance(p1,p2);cout<<"Thedistanceis"<<d<<endl;return0;}第36页,共60页,2023年,2月20日,星期四注:友元函数可以是普通函数,也可以是其它类的成员函数友元函数一般定义在类public部分,也可以定义在private部分友元函数降低了类的封装性,不利于代码复用。第37页,共60页,2023年,2月20日,星期四数据共享-友元类若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员(类内)。声明语法:将友元类名在另一个类中使用friend修饰说明。ClasA{friendclassB;Public:…friendclassC;Private:…}第38页,共60页,2023年,2月20日,星期四友元类举例classA{friendclassB;public:voidDisplay(){cout<<x<<endl;}private:intx;};classB{public:voidSet(inti);voidDisplay();private:Aa;};voidB::Set(inti){a.x=i;}voidB::Display(){a.Display();}但是,如:Bb;b.a.x=123;Error:‘a’:cannotaccessprivatememberdeclaredinclass‘B‘为什么?第39页,共60页,2023年,2月20日,星期四注:若一个类为另一个类的友元,则此类的所有成员函数都能访问对方类的私有成员友元关系不具有传递性、不具有对称性,友元关系是非等价关系第40页,共60页,2023年,2月20日,星期四数据共享-友元分析友元是C++提供的一种破坏数据封装和数据隐藏的机制。通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中被隐藏的信息。可以使用友元函数和友元类。为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。第41页,共60页,2023年,2月20日,星期四课堂练习1.定义一个date类,通过设计一个友元函数,求两日期之间的相差的天数下页例程第42页,共60页,2023年,2月20日,星期四#include"iostream.h"classdate{friendintdis_of_day(dated1,dated2);public: date(intyear,intmouth,intday) {this->year=year;this->mouth=mouth;this->day=day;}voidout(){cout<<this->year<<""<<mouth<<""<<day<<endl;}private:intyear;intmouth;intday;};第43页,共60页,2023年,2月20日,星期四longdis_of_day(dated1,dated2){ longcalc; calc=(d1.year-d2.year)*365+(d1.mouth-d2.mouth)*30+d1.day-d2.day; returncalc;}voidmain(){ dated1(1934,23,12),d2(1934,20,11); d1.out(); d2.out(); cout<<dis_of_day(d1,d2)<<endl;}返回第44页,共60页,2023年,2月20日,星期四共享数据的保护-常类型采用如下的共享数据保护措施

常类型的提出:各种形式的数据共享破坏了数据的隐秘性、数据的封装,如何保护被共享的数据?1.常引用:被引用的对象不能被更新。2.常对象:必须进行初始化(通过构造函数),不能被更新。3.常类成员:

(1)常数据成员通过构造函数初始化

(2)常函数成员问:什么是更新?第45页,共60页,2023年,2月20日,星期四1.常引用voiddisplay(constdouble&r)//常引用做形参,在函数中不能更新r所引用的对象。{cout<<r<<endl;

if(r=r)cout<<“ok”<<endl;//r=r或r=9.5;都认为错误,不许更新++r;//出错,不予许更新

}例:格式:const类型说明符&引用名第46页,共60页,2023年,2月20日,星期四2.常对象举例classA{public:intx,y;voidprt(){cout<<“x=:<<x<<“y=:”<<y<<endl;};Aconsta;//a是常对象,不能被更新main(){cout<<a.x<<endl;//输出默认值a.x=3;//错误,不许更新只能通过类的构造函数初始化}格式:类名const对象名例:第47页,共60页,2023年,2月20日,星期四3.1常成员函数#include<iostream.h>classR{public:R(intr1,intr2){R1=r1;R2=r2;}voidprint();voidprint()const;//构成重载private:intR1,R2;};格式:成员函数const

常成员函数不更新对象的数据成员常对象只能调用它的常成员函数第48页,共60页,2023年,2月20日,星期四voidR::print(){cout<<R1<<":"<<R2<<endl;}voidR::print()const{cout<<R1<<";"<<R2<<endl;

R1=11l;//error

}voidmain(){Ra(5,4);a.print();//调用voidprint()constRb(20,52);b.print();//调用voidprint()const}第49页,共60页,2023年,2月20日,星期四3.2常数据成员classA{public: A(inti); voidprint();

constint&r;private: constinta; staticconstintb;//静态常数据成员};格式:const数据成员。常数据成员只能通过类的构造函数置初值第50页,共60页,2023年,2月20日,星期四constintA::b=10;//静态成员赋值A::A(inti):a(i),r(a){}//构造函数赋值voidA::print(){cout<<a<<":"<<b<<":"<<r<<endl;}voidmain(){/*建立对象a和b,并以100和0作为初值,分别调用构造函数,通过构造函数的初始化列表给对象的常数据成员赋初值*/Aa1(100),a2(0);a1.print();a2.print();}100:10:1000:10:0输出结果第51页,共60页,2023年,2月20日,星期四注意:1.常引用的所指的“对象”不能被更新2.常对象的数据成员不允许被更新,通过常对象只能调用它的常成员函数,常成员函数不更新对象的数据成员。3.常成员函数说明格式中的const是函数类型的一个组成部分,在声明、定义实现部分都要带上,const关键字可以形成函数重载。4.常数据成员只能通过类的构造函数置初值。5.const位置问题,除了常函数成员外,const的位置是灵活的。对比类静态成员第52页,共60页,2023年,2月20日,星期四const的位置常引用:[const]类型说明符[const]引用名常对象:[const]类名[const]对象名常数据成员[const]类型说明符[const]成员名常函数成员类型说明符函数名()[c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论