数据共享和成员特性.ppt
《数据共享和成员特性.ppt》由会员分享,可在线阅读,更多相关《数据共享和成员特性.ppt(41页珍藏版)》请在三一办公上搜索。
1、第5章 数据共享和成员特性,5.1 静态成员,5.2 友元,5.3 成员其他特性,5.4 this指针,5.5 综合应用实例:栈类静态操作,5.1 静态成员,使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共享。静态数据成员的值是可以修改的,但它对每个对象都是一样的。1.定义和使用与静态变量相似,静态数据成员是静态存储(static)的,但定义一个静态数据成员与一般静态变量不一样,它必须按下列2步进行:(1)在类中使用关键字static声明静态数据成员。在类中声明静态数据成员,仅仅是说明了静态数据成员是类中的成员这个关系,即便用该
2、类定义对象时,该静态数据成员也不会分配内存空间。因此可以说,类中声明的静态数据成员是一种形式上的虚的数据成员。静态数据成员的实际定义是由下一步来完成。(2)在类外为静态数据成员分配内存空间并初始化。类中数据成员的内存空间是在对象定义时来分配的,但静态数据成员的内存空间是为所有该类对象所共享,只能分配一次,因而不能通过定义类对象的方式来分配,即其初值不通过构造函数来制定,必须在类的外部作实际定义才能为所有对象共享,其定义格式如下::=可见,在类外初始化的静态数据成员与全局变量初始化格式相似,只是须指明它所属的类。由于静态数据成员的静态属性static已在类中声明,因此在类外不可再指定static
3、。例如:,5.1.1 静态数据成员,5.1.1 静态数据成员,程序运行的结果如下:分析:(1)A中,由于使用了默认参数,因而使得默认构造函数和重载构造函数定义成一个构造函数。这种程序方法在实际应用时要小心使用。(2)程序中,类CSum中的私有数据成员nSum被声明成静态的,由于类中声明的nSum是虚的,因此它必须在类体外进行实际定义。若不指定初值,则默认为0。(3)main函数中,对象one初始化后,nSum值变为12。对象two由于调用的是(a=0,b=0)的默认构造函数,故nSum的值没有变化,仍然是12(注意构造函数体的语句“nSum+=a+b;”中的“+=”不是“=”)。因此,main
4、函数中前面两条输出语句的结果都是输出12。当执行“two.setSum(5);”后,nSum值被设为5。由于nSum是所有对象所共享,也就是说,nSum是所有对象的公共成员,因此对象one中的nSum的值也是5。,5.1.1 静态数据成员,2.几点说明(1)由于静态数据成员在类中所作的声明仅仅是一种声明该成员是属于哪个类的,它是形式上的虚的成员,还必须在类的外部作实际定义才能为所有对象共享,正因为如此,静态数据成员的实际定义和初始化本身是不受public、private和protected等访问属性的限制。(2)静态数据成员可看成是类中声明、类外定义的静态全局变量,因此它具有静态生存期,在程序
5、中从实际定义时开始产生,到程序结束时消失。也就是说,静态数据成员的内存空间不会随对象的产生而分配,也不会随对象的消失而释放。当然,静态数据成员的内存空间同样不能在类的构造函数中创建或是在析构函数中释放。(3)静态数据成员是类中的成员,它的访问属性同普通数据成员一样,可以为public、private和protected。当静态数据成员为public时,则在类外对该成员的访问和引用可有2种方式,一是通过对象来引用,二是直接引用。当直接引用时,应使用下列格式::,5.1.1 静态数据成员,例如,有:class CSumpublic:static int nSum;/声明公有型静态数据成员;int
6、CSum:nSum=0;/静态数据成员的实际定义和初始化则在main函数中可有下列引用:int main()CSum one;one.nSum=10;/通过对象来引用CSum:nSum=12;/直接引用coutone.nSumendl;/输出12return 0;代码中,引用公有型静态数据成员nSum的2种方式都是合法的,也是等价的。,5.1.2 静态成员函数,静态成员函数和静态数据成员一样,它们都属于类的静态成员,但它们都不专属于某个对象的成员,而是所有对象所共享的成员。因此,对于公有型(public)静态成员来说,除可用对象来引用外,还可通过“类名:成员”直接来引用。在类中,静态数据成员可
7、以被成员函数引用,也可以被静态成员函数所引用。但反过来,静态成员函数却不能直接引用类中说明的非静态成员。假如,静态成员函数可以引用了类中的非静态成员,例如:class CSumpublic:static void ChangeData(int data)nSum=data;/错误:引用类中的非静态成员public:int nSum;则当执行语句:CSum:ChangeData(5);/合法的静态成员引用,5.1.2 静态成员函数,时必然会出现编译错误,这是因为此时CSum类的任何对象都还没有创建,nSum数据成员根本就不存在。即使是创建了CSum类对象,此时这种形式的静态成员函数调用根本无法确
8、定函数中所引用的nSum是属于哪个对象,因此静态成员函数只能引用静态数据成员,因为它们都是独立于对象实例之外而为对象所共享的成员。下面来看一个示例,它是用静态成员来实现数据插入、输出和排序操作。同普通成员函数,类中的静态成员函数也可在类中声明,而在类外实现。由于类CData中所有的成员都声明成了静态的,因此在main函数直接通过“类名:成员”的形式来引用其public成员,通过静态成员函数Add在静态数组成员data中设置并添加数组,每添加一次,静态指针成员pCur的指向就向下移动一次,使其指向下一个数组元素的内存空间。静态成员函数Print和Sort分别将data数组中的已有数组输出和排序。
9、程序运行的结果如下:,可见,若将相同类别的操作均用公有型静态成员函数来实现,则无需通过对象就可引用类中的成员,此时的类成了一种工具集,这在强调程序算法的场合下得到了广泛应用。,5.1.2 静态成员函数,但是,静态成员函数可以把类的引用或指针作为形参以间接访问非静态成员。例如:例Ex_VisitNonStatic 静态成员函数间接访问非静态成员#include using namespace std;class CSum public:static int getsum(CSum,5.1.2 静态成员函数,程序运行的结果如下:这种将引用或者指针作为静态成员函数形参传递的用法,与非静态成员函数里t
10、his指针(后面讨论)的功能有异曲同工之妙。需要强调的是:(1)静态成员中的“静态(static)”与普通静态变量和静态函数中的“静态”含义是不一样的。普通静态变量中的“静态”是使用静态存储内存空间,而类中的静态数据成员的“静态”是对象数据共享的声明,并非具有实际意义的静态存储内存空间。普通静态函数中的“静态”是表示本程序文件的内部函数,而类中的静态成员函数的“静态”表示该成员函数仅能访问静态数据成员,是为所有该类对象共享的声明方式。(2)类的静态数据成员的内存开辟和释放只能通过静态成员函数来实现,而不能通过类的构造函数和析构函数来完成。C+中也没有静态构造函数和静态析构函数。,5.2 友元,
11、通常,类的私有型(private)数据成员和保护型(protected)数据成员只能在类中由该类的成员函数来访问,类的对象以及外部函数只能访问类的公有型(public)成员函数,类的私有和保护型数据成员只能通过类的成员函数来访问,如图5.1(a)所示。但是,如果在类中用friend关键字声明一个函数,且该函数的形参中还有该类的对象形参,这个函数便可通过形参对象或通过在函数体中定义该类对象来访问该类的任何私有和保护型数据成员,如图5.1(b)所示。这就好比一个人的私密可以让“密友”知道一样,用friend声明的这个函数就称为这个类的友元函数。除友元函数外,友元还可以是类,即一个类可以作另一个类的
12、友元,称为友元类。例如,当B类作为A类的友元时,这就意味着在B类中通过A类对象来访问A类中的所有成员。可见,采用友元机制,通过类对象可以访问或引用类中的所有成员。这样,即使通过友元来修改数据成员时,修改的也仅仅是某个对象的数据成员,从而既保证了类的封装性,也为外部访问类的私有和保护型成员提供了方便。,5.2.1 友元概述,5.2.1 友元概述,图5.1 外部函数和友元对类成员的访问关系,5.2.2 友元函数,友元函数可分为友元外部函数和友元成员函数。当一个函数f是A类的友元时,若f还是另一个类B的成员函数时,则这样的友元称为友元成员函数;若f不属于任何类的成员,则这样的友元称为友元外部函数。友
13、元外部函数常直接简称为友元函数。1.友元函数友元函数在类中定义的格式如下:friend(形参表)从格式中可以看出,友元函数和类的成员函数定义格式基本一样,只是友元函数前面用一个关键字friend来修饰。由于友元函数与类的关系是一种“友好(friendship)”关系,因此友元函数不属于类中的成员函数,它是在类中声明的一个外部函数。需要说明的是:(1)友元函数的定义可在类中进行,也可将友元函数在类中声明,而将其实现在类外定义。但在类外定义时,不能像成员函数那样指明它所属的类。(2)由于友元函数是一个外部函数,因此它对类中的成员访问只能通过类对象来进行,而不能直接去访问。这里的对象可以通过形参来指
14、定,也可在友元函数中进行定义。(3)由于友元函数是类中声明的外部函数,因而它跟成员的访问权限private、protected和public没有任何关系,因此它的声明可以出现在类中的任何部分,包括在private和public部分。但为了程序的可读性,常将友元函数声明在类体的开头或是最后。,5.2.2 友元函数,(4)由于友元函数不是类的成员,因此它在调用时不能指定其所属的类,更不能通过对象来引用友元函数。(5)大多数外部函数对类中的数据操作是采用形参对象的方式,通过对象的“引用”传递,达到修改对象数据的目的。对于友元函数,也应该采用这种方式,只是友元函数还能修改对象的私有和保护型数据成员。下
15、面来举一个例子,它是通过友元函数将一个点(CPoint)的位置发生偏移。,5.2.2 友元函数,例Ex_FriendFun 使用友元函数#include using namespace std;class CPointfriend CPoint Inflate(CPoint,5.2.2 友元函数,在类CPoint中,Inflate是在类中声明,在类外定义的友元函数。它有两个形参:一是引用形参对象pt,二是int形参变量nOffset。由于在友元函数中,对象的所有数据成员可以直接访问,因此可直接将形参对象pt的私有数据成员直接加上nOffset指定的偏移量。由于Inflate指定的pt对象是引用
16、传递,因此对pt内容的修改也就是对实参对象内容的修改。程序运行的结果如下:2.友元成员函数友元成员函数在类中定义的格式如下:friend:(形参表)由于友元成员函数还是另一个类的成员函数,因此这里的类名是指它作为成员所在的类名。同成员函数一样,友元成员函数的定义既可在类中进行,也可将友元成员函数在类中声明,而将其实现在类外定义。但在类外定义时,应像成员函数那样指明它所属的类。例如:,5.2.2 友元函数,在类CRect中声明了一个友元函数Inflate,由于它还是类CPoint的成员函数,因此Inflate既可以直接访问CPoint的所有成员,也可以通过CRect类对象访问类CRect中的所有
17、成员。由于在类CPoint中的Inflate函数的形参含有CRect对象,而此时CRect类还没有定义,因此需要在类CPoint前先作CRect类的声明,以便后面能使用CRect数据类型。程序运行的结果如下:,下面来看一个例子。,在类CPoint的定义中,类COther被声明成CPoint的友元类。这样,在类COther中,可通过CPoint对象pt访问类CPoint的所有成员。程序运行的结果如下:,5.2.3 友元类,总之:(1)友元关系反映了程序中类与类之间、外部函数和类之间、成员函数和另一个类等之间的关系,这个关系是单向的,即当在CPoint中声明COther是CPoint的友元类时,只
18、能在COther类中通过CPoint对象访问CPoint类的所有成员,而在CPoint类中是无法访问COther类的私有和保护型成员。(2)一个类中的友元并非是该类的成员,由于“friend”关系,因而友元只能通过对象来访问声明友元所在类的成员。而静态成员是类的一个成员,它本身具有不同的访问属性,只是对于公有静态成员来说,它可以有对象访问和“类名:静态成员”2种等价的访问方式。(3)与友元函数相比,静态成员函数只是修改类的静态数据成员,而对于友元来说,由于通过对象可以修改声明友元所在类的所有数据成员,因而友元函数比静态成员函数更加危险,而且友元类使这种危险更加扩大。因此,在类程序设计中,静态成
19、员和友元一定要慎用!,5.3 成员其他特性,关键字const不仅可以修饰数据成员,而且可以修饰成员函数。1.常数据成员在类中使用const关键字进行声明的数据成员,称为常数据成员,其声明格式如下:数据类型 const 数据成员名;const数据类型 数据成员名;上述两种格式是等价的,都是用来声明const数据成员。const除了修饰一般数据成员外,还可修饰引用数据成员和静态数据成员,分别称为常引用数据成员和常静态数据成员。同const变量一样,这些常数据成员的值都是不能被更新的,且必须进行初始化。对于一般常数据成员和常引用数据成员来说,其初始化只能通过构造函数中的成员初始化列表的方式来进行。而
20、对于静态常数据成员来说,则须在类外进行定义并初始化,初始化的方式和一般静态数据成员相同。例如:,5.3.1 const成员,5.3.1 const成员,例Ex_ConstData 常数据成员的使用#include using namespace std;class COnepublic:COne(int a):x(a),r(x)/常数据成员的初始化 void Print();public:const int,5.3.1 const成员,程序中,类COne声明了3个常数据成员,分别是一般常数据成员x、常静态数据成员y和常引用数据成员r。要注意这些常数据成员的初始化方式,常静态数据成员y是在类外进
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据 共享 成员 特性
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-6296257.html