类的数据共享与保护.ppt_第1页
类的数据共享与保护.ppt_第2页
类的数据共享与保护.ppt_第3页
类的数据共享与保护.ppt_第4页
类的数据共享与保护.ppt_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

第6章 类的数据共享与保护,本章主要内容,对象(变量)的作用域、可见性与生存期 类的静态成员 类的友元 常引用、常对象和常成员,6.1 对象(变量)的作用域、可见性和生存期,对象(变量)的作用域:指对象的有效范围。 - 一般情况下,对象在其作用域内是可见的和存在的,对象的作用域、可见性和生存期三者是一致的。 对象(变量)的可见性:指不同作用域的同名对象在其作用域范围内的某一处是否可被引用。,对象(变量)的生存期:指对象从诞生(占据内存)到结束(不占内存)的这段时间。在生存期内, 对象或变量将保持它的值不变, 直到它们被更新为止。 -对象(变量)的生存期分为动态生存期和静态生存期两种。,6.1.1 对象(变量)的作用域,局部对象(变量):(函数内)块作用域 - 从声明处开始到块结束的花括号为止 形参对象(变量):函数作用域 - 在整个函数内有效,成员对象(变量):类作用域 - 在整个类内有效,即在所有成员函数内有效 全局对象(变量):文件作用域 - 在整个文件内有效,6.1.2 对象(变量)的可见性,一般情况下对象(变量)在其作用域范围内的任一处是可见的,即可被引用。 在有不同作用域的多个同名对象(变量)的情况下,外层对象(变量)在内层不可见, 被隐藏起来。,作用域关系图,不同作用域的同名对象的 包含关系如右图所示。 被隐藏的成员对象(变量) 可加“类名:”来显式地引用, 被隐藏的全局对象(变量) 可加“:”来显式地引用。,6.1.3 对象(变量)的生存期,对象(变量)的生存期:动态生存期、静态生存期。 动态生存期:对象(变量)在程序运行期间随时诞生和消失,如局部变量、形参变量、成员变量。 静态生存期:对象(变量)在程序运行期间一直存在,如全局变量。,C语言中静态局部变量:作用域与生存期不一致。 C+在类的成员函数中定义一个静态局部变量:该类的所有对象在调用这个成员函数时将共享这个变量。 C+类的成员为静态成员:静态成员为该类所有对象所共享,它不属于某个对象的,见下节。 程序实例,6.2 静态成员(static),在C语言中,当把函数的一个局部变量说明为静态的,则该变量在函数调用结束后其值仍然存在,但其它函数不能引用。若下次再调用该函数,则该变量的值不再重新初始化为0,函数可以使用上次调用所保留的值。,在C+中,对于某个类所定义的每一个对象,都有其属于自身的数据成员与成员函数,不同对象之间的成员是互不相干的,这类似于C中函数内的局部变量,不同时间函数调用的局部变量是互不相干的。但它们都同名。,因此,在C+中,当把类的某个成员用关键字static说明为静态成员时, 就是把该成员定义为在该类范围内的全局成员,即无论这个类建立了多少个对象,所有对象都共用这个成员。因此,静态成员的主要用途是定义类的各个对象所共用的数据成员或成员函数,其中尤其是数据成员。,下面对静态数据成员和静态成员函数分别进行讨论。,6.2.1 静态数据成员,在一个类中,若将一个数据成员说明为static,则该数据成员称为静态数据成员,无论建立多少个该类的对象,都只有一个共同的数据成员。static数据成员在编译时按全局变量方式被分配存储单元并初始化,默认的初始值为零。,欲声明一个成员为静态的,只要在其前方加上关键字static即可, 如在Point类定义一个静态数据成员countP : static int countP;,静态数据成员的使用与普通数据成员的使用并无差异,但必须注意两点:,a.由于静态数据成员在该类范围内是一个全局变量,因此必须在类定义外的全局范围中给它赋初值,然后才能使用。如下所示: int Point:countP=0;,给静态数据成员赋初值时必须同时指名数据类型与所属的类,用类名加作用域运算符来限定。这里的数据类型必须与在类中声明的数据类型一致。,由于静态数据成员并不特别属于某一个对象,上述这样的赋初值语句只能在整个程序中出现一次。因此,程序员最好不要把静态成员的初始化定义在头文件中,因为头文件可能在程序中多次被引入使用,否则将发生错误。,b.当静态数据成员声明于类的public区时,由于它并不特别属于某一个对象, 在类范围内是全局的,因此可以在程序的任何地方直接引用该静态数据成员,但使用时必须加上类范围的限制,如: cout“对象个数为:“Point:countP;,下面我们来看看例5-4 (P138)。,由于静态数据成员是所有同类对象所共用的数据,所以 A.getC(); B.getC(); 这两个输出语句的结果是相同的,即: 对象个数为:2 对象个数为:2,从程序的最后两句可以看出,类的public数据成员有两种使用方法:,6.2.2 静态成员函数,成员函数也可以被声明为静态的。当一个成员函数被声明为static时,表明该静态成员函数只属于一个类,而不属于该类的任何对象。因此,在访问静态成员函数时,最好用类名加作用域运算符来调用该静态成员函数。,对象名.数据成员 或 类名:数据成员 第一种方式主要用于非静态数据成员,第二种主要用于静态数据成员。,实际上,当某成员函数只使用静态数据成员时,应该把该成员函数定义为静态成员函数。这是因为,一个仅使用到静态数据成员的成员函数通过某类的对象来调用是没有任何意义的,且容易造成阅读上的混淆,阅读者无法从程序中直接看出该成员函数引用了静态数据成员。,因此 A.getC( ); B.getC( ); 改为: Point:getC( ); Point:getC( ); 更为妥当。,见例5-5 (P140)。,另一方面, 静态成员函数不属于某个对象的, 因此, 在静态成员函数访问非静态成员时,必须要指明所要访问的对象。例如,若在getC中要访问非静态成员X, 则getC必须修改为:,见修改后的例5-5 析构函数有代码,static void getC(Point ,则main函数中的调用语句改为: Point:getC(A); Point:getC(B);,6.3 友元(friend),前面已讲过, 一个对象的私有数据只能通过成员函数进行访问。这种数据封装的方法虽有许多优点,但在某些情况下也带来许多不便, 如某个函数需要使用多个类的多个相关数据, 或类Y的所有成员函数要访问类X的私有数据。出于效率而非技术的考虑, C+提供了友元(friend)这样一种辅助手段, 允许外面的类或函数去访问一个类的私有数据。,友元分为两种情况:将一个普通函数声明为某类的友元和将一个类声明为另一个类的友元。,6.3.1 友元函数,要声明一个普通函数为某类的友元, 只要在该类定义中任何一处(不管是private、protected或是public区)提供对该函数的声明,并在其最前方加上关键字friend即可。下面是计算两点距离的实例:,class Point int X,Y; friend float fdist(Point ,与成员函数一样,友元函数可以在类Point的内部定义,也可以在类Point的外部定义。当在类外定义时, 友元函数不需要加“类:”。如上述fDist函数在类Point外定义:,double fDist (Point 见例5-6 (P143),请注意友元函数与成员函数在定义和使用上的区别。成员函数与友元函数的主要区别是成员函数是属于某个类的,而友元函数不属于某个类。,在友元函数中,必须指定所要访问的对象,这在三个地方体现出来:, 在参数中有2个Point类的引用; 在实现代码中通过引用对象p1和“.”来使用数据成员; 使用友元函数(即调用该友元函数)时必须有该类对象作为实参。,6.2.2 友元类,我们可以将类A声明为类B的友元,这样类A的所有成员函数就可以访问类B的私有数据。例如:,class A; /一个类声明语句 class B friend A; /声明A为B的友元类 int i; void m_func( ); ;,class A public: void f_f1(B ,对于友元类的成员函数的使用和定义方式,由于它兼具有类和友元函数的双重特点,所以它的使用和定义方式颇具特色,具体如下:,a.由于它是属于某个类(A),所以在类外定义时必须加作用域运算符来限定它属于某一类(A)的,在使用时必须加对象名和成员运算符来指定哪一个对象调用它;,b.由于它是另一个类(B)的友元,所以在其参数中必须用该类(B)的对象和引用作为形参。,c.在实现代码上,必须用该类(B)的对象名加成员运算符来使用该类(B)的私有数据。,见例(P145)。,友元说明只有在确实必要时才应使用,即在没有它时必须建立一个复杂的类等级的时候才使用。从性质上来说,友元是一种数据共享,它破坏了类的封装性,因此要尽量少用。,在使用友元时还要注意:(1)友元不具有可传递性,如B是A的一个友元,A是C的一个友元,并不能得出B是C的友元的结论。(2)友元关系是单向的, 如果B类是A类的友元,B类的成员函数可以访问A类的私有数据,但A类的成员函数不能访问B类的私有数据。(3)友元关系不能被继承,如果B类是A类的友元,B类的派生类不能自动成为A类的友元。,6.4 常对象和常成员(const),虽然数据隐藏保证了数据的安全性,但各种形式的数据共享却又不同程度地破坏了数据的安全。因此,对于既需要共享、又需要防止改变的数据应该声明为常量。因为常量在程序运行期间是不可改变的,所以可以有效地保护数据。,本节介绍用const定义的常对象、常成员和常引用。,6.4.1 常对象,常对象是指常类型对象,即对象常量,定义的语法形式为: 类名 const 对象名(初值); 或 const 类名 对象名(初值);,定义常对象同样要赋初值, 并且该对象不得再更新。另外,常对象只能调用它的常成员函数,而不能调用其他成员函数。参见下面的常成员函数。,6.4.3 常成员,使用const关键字说明的函数为常成员函数,常成员函数据说明格式如下: 类型说明符 函数名(参数表)const;,1. 常成员函数,注意: (1) const是函数类型的一个组成部分,因此在实现部分也要带const关键字, 并且可用于对重载函数的区分。,(2) 常成员函数不更新对象的数据成员,也不能调用该类中没有用const修饰的成员函数。 (3) 常对象只能调用它的常成员函数,而不能调用其他成员函数。 见例5-7(P147-148),用const说明的数据成员称为常数据成员。常数据成员的值在任何函数中都不能被更改,必须编写构造函数并采用初始化列表的方式进行初始化。 见例5-8(P148),2. 常数据成员,6.4.1 常引用,函数的参数可以被说明为常引用(用const修饰),则在该函数内不能修改该形参的值。 见例5-

温馨提示

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

评论

0/150

提交评论