第九章数据的共享与保护—变量的生存期与作用域、常类型、常成员函数2本章主要内容变量的生存期与作用域同类对象间的数据共享—静态成员共享数据的保护(常成员和常对象)3对象的生存期对象(包括简单变量)都有诞生和消失的时刻。所谓对象的生存期就是一个对象在程序运行过程中有效存在的时间,也就是从对象的诞生到对象的消亡这段时间。不同的对象和变量具有不同的生存期,比如全局变量和静态变量具有静态生存期(静态生存期与程序的运行期相同),而局部非静态变量有动态生存期(动态生存期为对象的声明开始点到该对象消亡处)。4不同变量的生存期#includeiostreamusingnamespacestd;doubleCF=5.1;//全局变量具有静态生存期classexam{public:doubletemp;exam(doublex=0):temp(x){coutconstructedendl;};~exam(){coutdestructed!endl;}};5例:不同变量的生存期intmain(){intadd_num1(3),add_num2(4);voidadd(intx,inty);{examtemp(CF);couttemp.tempendl;intx=3;}add(add_num1,add_num2);}6voidadd(intx,inty){staticintz=3;inta=4;coutsumisx+y+z+aendl;}7作用域及可见性作用域是指一个标志符在程序中的有效范围。作用域一般可以分为四个类型:一、函数原型作用域;二、局部作用域(块作用域);三、类作用域;四、文件作用域。函数原型作用域是指在函数原型声明时形参的作用范围。在函数原型中,如果有形参,则一定要包含形参的类型说明。而形参的作用范围就在函数形参列表的左右括号之间,在程序的其他地方不能引用这个标识符,此标识符的作用域成为函数原型作用域。8作用域及可见性局部作用域是指在一个程序块中或者某个函数体内的作用范围。如用大括号括起来的程序块:{inta,b;cinab;{intc;}}其中a,b具有第一层的块作用域,而c在第二层的块,因此其作用范围在第二层的块中,这些都可以称为局部作用域。9作用域及可见性在类中声明的变量和对象,因为其具有类作用域,我们需要通过“.“运算符或者域运算符“::”来访问。除了以上各种情况声明的标识符具有文件作用域,这样声明的标识符起作用开始于声明点,结束于文件尾。标识符的可见性是指标识符在程序中能否被引用。10作用域及可见性作用域可见性的一般规则是:–标识符要声明在前,引用在后。–在同一作用域中不能声明同名的标识符。–在没有互相包含关系的不同的作用域中声明的同名标识符互不影响。–如果在两个或者多个具有包含关系的作用域中声明了同名标识符,外层的标识符在内层不可见,或者说外层的同名标识符被隐藏了。11例9-3:静态数据成员#includeiostream#includestringusingnamespacestd;classStudent{private:intnum;//学号charname[20];//名字public:staticintcount;//用于计数的静态变量Student(){count++;};//构造函数Student(char*,int_num=0);//构造函数voidGetName();//获取名字函数intGetNum();//获取学号函数~Student(){count--;};//析构函数};变量的生存期与作用域12例9-3:静态数据成员intStudent::count=0;//静态变量初始化Student::Student(char*_name,int_num){strcpy(name,_name);num=_num;count++;}voidStudent::GetName(){coutnameendl;}intStudent::GetNum(){returnnum;}变量的生存期与作用域13例9-3:静态数据成员intmain(){Studentstu[2];coutthenumberofstudentsis:Student::countendl;coutthenumberofstudentsis:stu[0].countendl;return0;}变量的生存期与作用域thenumberofstudentsis:2thenumberofstudentsis:2运行结果:变量的生存期与作用域15静态函数成员静态函数的声明在类中用关键字static声明。静态成员函数可以直接访问该类的静态数据和函数成员。而访问非静态数据成员必须通过参数传地方式得到对象名,然后通过对象名访问。同类对象间的数据共享—静态成员16例9-4:对静态数据成员的访问#includeiostream#includestringusingnamespacestd;classStudent{private:intnum;//学号charname[20];//名字public:staticintcount;//用于计数的静态变量Student(){count++;};//构造函数Student(char*,int_num=0);//构造函数voidGetName();//获取名字函数intGetNum();//获取学号函数staticintGetCount(){returncount;}//静态成员函数~Student(){count--;};//析构函数};变量的生存期与作用域17例9-4:对静态数据成员的访问intStudent::count=0;//静态变量初始化Student::Student(char*_name,int_num){strcpy(name,_name);num=_num;count++;}voidStudent::GetName(){coutnameendl;}intStudent::GetNum(){returnnum;}变量的生存期与作用域18例9-4:对静态数据成员的访问intmain(){Studentstu1,stu2;coutthenumberofstudentsis:Student::GetCount()endl;return0;}变量的生存期与作用域thenumberofstudentsis:2运行结果:19常引用类的私有数据属性给数据的安全提供了一定的保障,但是数据的共享必定带来数据安全隐患,如果不小心很有可能篡改了数据,影响了数据的安全。常引用,在引用时加一个const修饰符,保证引用访问时不更改该对象。共享数据的保护20例9-5:常引用#includeiostream#includeiomanipusingnamespacestd;intmain(){inta,b;voidcompare(constint&x,constint&y);//比较函数的声明coutpleaseentertwointeger:endl;cinab;compare(a,b);}共享数据的保护21例9-5:常引用voidcompare(constint&x,constint&y)//比较函数的定义{if(x==y){couttheyareequal!endl;}elseif(xy){couttheformerisbiggerendl;}else{coutthelasterisbiggerendl;}}共享数据的保护22pleaseentertwointeger:58thelasterisbigger运行结果:共享数据的保护23常成员类的私有数据属性给数据的安全提供了一定的保障,但是数据的共享必定带来数据安全隐患,如果不小心很有可能篡改了数据,影响了数据的安全。常数据成员:使用const说明的数据成员。共享数据的保护24常成员常成员函数–使用const关键字说明的函数。–常成员函数不更新对象的数据成员。–常成员函数说明格式:类型说明符函数名(参数表)const;这里,const是函数类型的一个组成部分,因此在实现部分也要带const关键字。–const关键字可以被用于参与对重载函数的区分共享数据的保护25例9-6:常成员数据//CircleCal.h#ifndefCircle#defineCircleclassCircleCal{private:doubleRadius;//定义半径constdoublePI;public:CircleCal(doubler=0):PI(3.1415)//缺省半径值,常量的初始化{Radius=r;};doubleCal();//声明计算面积函数~CircleCal(){};};#endif共享数据的保护26例9-6:常成员数据//CircleCal.cpp#includeiostream#includecmath#includeCircleCal.husingnamespacestd;doubleCircleCal::Cal()//定义计算面积的值{returnpow(Radius,2)*PI;}共享数据的保护27例9-6:常成员数据//9_6.cpp#includeiostream#includeiomanip#includeCircleCal.husingnamespacestd;intmain(){CircleCalR1(2.5),R2;couttheaeraofR1is:setw(5)R1.Cal()endl;couttheaeraofR2is:setw(5)R2.Cal()endl;return0;}共享数据的保护28theaeraofR1is:19.6344theaeraofR2is:0运行结果:共享数据的保护29例9-7:常成员函数//CircleCal.h#ifndefCircle#defineCircleclassCircleCal{private:doubleRadius;//定义半径constdoublePI;public:CircleCal(doubler=0):PI(3.1415)//缺省半径值,常量的初始化{Radius=r;};doubleGetR()const;//声明常函数doubleCal();//声明计算面积函数~CircleCal(){};};#endif共享数据的保护30例9-7:常成员函数//CircleCal.cpp#includeiostream#includecmath#includeCircleCal.husingnamespacestd;doubleCircleCal::Cal()//定义计算面积的值{returnpow(Radius,2)*PI;}doubleCircleCal::GetR()const//定义常函数的时候不可将const省去{Radius=3;//错误!不可以改变Radius的值returnRadius;}共享数据的保护31例9-7:常成员函数//9_7.cpp#includeiostream#includeiomanip#includeCircleCal.husingnamespacestd;intmain(){CircleCalR1(2.5),R2;couttheaeraofR1is:setw(5)R1.GetR()endl;couttheaeraofR2is:setw(5)R2.GetR()endl;return0;}共享数据的保护32theaeraofR1is:2.5theaeraofR2is:0运行结果:共享数据的保护33常对象常对象就是对象在生存期内不可更改的对象。常对象首先需要被初始化,然后使用,在使用