C++语言程序设计实验答案数据的共享与保护范本模板.docx
- 文档编号:10669672
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:42
- 大小:160.41KB
C++语言程序设计实验答案数据的共享与保护范本模板.docx
《C++语言程序设计实验答案数据的共享与保护范本模板.docx》由会员分享,可在线阅读,更多相关《C++语言程序设计实验答案数据的共享与保护范本模板.docx(42页珍藏版)》请在冰豆网上搜索。
C++语言程序设计实验答案数据的共享与保护范本模板
实验05数据的共享与保护(2学时)
(第5章数据的共享与保护)
一、实验目的
(1)观察程序运行中变量的作用域、生存期和可见性.
(2)学习类的静态成员的使用。
(3)学习多文件结构在C++程序中的使用。
二、实验任务
5_1运行下面的程序,观察变量x、y的值。
//lab5_1。
cpp
#include
usingnamespacestd;
voidfn1();
intx=1,y=2;
intmain(){
cout〈<"开始.。
.”〈 cout〈〈”x="< cout<<"y=”〈 cout<<”在main()中求x和y的值。 。 ."〈 intx=10,y=20; cout〈〈”x=”〈〈x〈 cout〈<”y="<〈y< cout〈〈"进入函数fn1().。 。 ”〈〈endl; fn1(); cout<<”返回main()”<〈endl; cout<<"x=”〈 cout〈〈”y=”〈〈y〈 return0; } voidfn1(){ inty=200; cout<<”x=”< cout〈<”y="〈〈y<〈endl; } 5_2实现客户机(CLIENT)类. 声明字符型静态数据成员ServerName,保存其服务器名称;声明整型静态数据成员ClientNum,记录已定义的客户数量;定义静态函数ChangeServerName()改变服务器名称。 在头文件client.h中声明类,在文件client.cpp中实现,在文件lab5_2。 cpp中测试这个类,观察相应的成员变量取值的变化情况。 三、实验步骤 1。 (验证)运行lab5_1。 cpp程序,观察程序输出. 全局变量的作用域为文件作用域,在整个程序运行期间有效,但如果在局部模块中声明了同名的变量,则在局部模块中,可见的是局部变量,此时,全局变量不可见; 而局部变量的生存期只限于相应的程序模块中,离开相应的程序模块,局部变量x、y就不再存在,此时同名的全局变量重新可见。 程序名: lab5_1.cpp。 ★程序的运行结果: 2.(编程)实现客户机(CLIENT)类。 新建一个空的项目lab5_2,添加头文件client。 h,在其中声明类CLIENT,注意使用编译预处理命令;再添加源程序文件client.cpp,在其中实现CLIENT类,注意静态成员变量的使用方法;再添加文件lab5_2。 cpp,在其中定义main()函数,测试CLIENT类,观察相应的成员变量取值的变化情况。 提示: 访问一台服务器的客户总数。 静态成员为类的属性,为所有的类的对象共同拥有。 再定义两个静态成员函数,分别显示服务器名和客户总数。 构造函数用于增加一个客户,析构函数用于减少一个客户。 定义一个对象,再定义第二个对象,然后减少一个对象。 参考程序输出结果: ★程序及运行结果: (1)类声明头文件client。 h //client.h #ifndefCLIENT_H #defineCLIENT_H //其中的静态成员为类的属性,为所有的类的对象共同拥有 classclient{ public: client(); ~client(); staticvoidChangeServerName(charss);//改变服务器名称 staticvoidshowServerName(); staticvoidshowClientNum(); private: staticcharServerName;//保存服务器名,引用性说明 staticintClientNum;//记录已定义的客户(即对象)数量,引用性说明 }; #endif (2)类实现程序文件client。 cpp //client.cpp #include #include"client.h” usingnamespacestd; client: : client(){ClientNum++;}//增加一个对象(客户) client: : ~client(){ClientNum——;}//减少一个对象(客户) voidclient: : ChangeServerName(charsn){ServerName=sn;}//无static voidclient: : showServerName(){cout〈<"服务器名: ”〈〈ServerName< voidclient: : showClientNum(){cout〈<”客户总数: "〈 //必须在文件作用域的某处用类名限定进行定义性说明,这时也可以进行初始化. charclient: : ServerName=’A';//无static intclient: : ClientNum=0; (3)主函数文件lab5_2。 cpp //lab5_2。 cpp #include #include"client。 h" usingnamespacestd; voidmain(){ client: : showServerName();//初始状态 client: : showClientNum();//类名引用静态成员函数 client: : ChangeServerName('B'); clienta;//增加一个客户 a。 showServerName();//对象名引用静态成员函数 a。 showClientNum(); { clientb;//增加一个客户 b。 showServerName(); b。 showClientNum(); }//减少一个客户 client: : showServerName(); client: : showClientNum(); } (4)运行结果 附: 第5章数据的共享与保护 5。 1标识符的作用域与可见性P146 5。 1.1作用域 作用域是一个标识符在程序正文中有效的区域。 C++的作用域有: 函数原型作用域、块作用域(局部作用域)、类作用域、文件作用域。 1。 函数原型作用域 在函数原型声明时形式参数的作用范围. 例, doubleArea(doubleradius); 其中标识符radius的作用(或称有效)范围在形参列表的左、右括号之间,称标识符radius的作用域是函数原型作用域. 由于在函数原型的形参表中起作用的只是形参类型,标识符并不起作用,可省略。 2。 局部作用域(块作用域) 例: 形参作用域: 从形参列表中的声明处开始,到整个函数体结束处止。 b和c都具有块作用域,是不同的块作用域。 块是一对大括号括起来的一段程序。 此例,函数体是一个块,if语句后的分支体又是一个较小的块,二者是包含关系. 在块中声明的标识符,其作用域从声明处开始,一直到块结束的大括号为止. 具有块作用域的变量也称为局部变量。 3.类作用域 类是一组有名成员的集合,类X的成员m具有类作用域,对m的访问方式如下: (1)若在X的成员函数中无同名的局部作用域标识符,则在该函数内可访问成员m. (2)通过表达式x.m或X: : m。 这正是程序中访问对象成员的最基本方法。 (3)通过prt->m这样的表达式,其中prt为指向X类的一个对象的指针。 4.命名空间作用域 命名空间 大型程序通常由不同模块构成,不同模块中的类和函数之间可能发生重名,将引发错误。 命名空间可以解决类名、函数等的命名冲突. 命名空间语法形式: namespace命名空间名{ 命名空间内的各种声明(函数声明、类声明、……) } 例 namespaceSomeNs{ classSomeClass{.。 .}; } 特殊的命名空间 _全局命名空间: 默认的命名空间 _匿名命名空间: 对每个源文件是唯一的 命名空间作用域 一个命名空间确定了一个命名空间作用域 引用其它命名空间作用域中的标识符 _命名空间名: : 标识符名 _例: 声明一个SomeClass型的对象 SomeNs: : SomeClassobj1; 将其它命名空间作用域的标识符暴露于当前作用域 _对指定标识符 using命名空间名: : 标识符名; _对所有标识符 usingnamespace命名空间名; 例5—1中所声明的全局变量就具有文件作用域,它们在整个文件中都有效。 例5—1作用域实例。 #include〈iostream> usingnamespacestd;//使得在当前文件中可直接引用std命名空间的标识符cout inti;//全局变量,文件作用域 namespaceNs{ intj;//在Ns命名空间中的全局变量 } voidmain() { i=5;//文件作用域的i赋初值 Ns: : j=6;//为全局变量j赋值 {//子块1 usingnamespaceNs;//使得在当前块中可直接引用Ns命名空间的标识符 inti;//局部变量,块作用域 i=7; cout<〈”i=”〈 cout<<”j="〈 } cout<<”i="〈 } 参考(cout,endl是命名空间std中的全局变量): #include //usingnamespacestd;//使得在当前文件中可直接引用std命名空间的标识符cout,endl inti;//全局变量,文件作用域 namespaceNs{ intj;//在Ns命名空间中的全局变量 } voidmain() { i=5;//文件作用域的i赋初值 Ns: : j=6;//为全局变量j赋值 {//子块1 usingnamespaceNs;//使得在当前块中可直接引用Ns命名空间的标识符 inti;//局部变量,块作用域 i=7; std: : cout〈<”i=”<〈i〈〈std: : endl;//输出7 std: : cout<〈”j="<〈j〈 : endl; } std: : cout<<”i="〈〈i< : endl;//输出5 } 具有文件作用域的变量也称为全局变量. 5.1。 2可见性P150 可见的标识符程序运行到某一点,能够引用到的标识符。 文件作用域最大,接下来依次是类作用域和块作用域。 图5-1作用域关系图 可见性表示从内层作用域向外层作用域“看"时能看到什么. 作用域可见性的一般规则: _标识符声明在前,引用在后。 _同一作用域,不能声明同名标识符。 _在没有包含关系的不同作用域中声明的同名标识符互不影响。 _在具有包含关系的作用域中声明了同名标识符,则外层标识符在内层不可见。 例5-l中,文件作用域与块作用域相互包含. #include usingnamespacestd; inti;//全局变量,文件作用域 namespaceNs{ intj;//在Ns命名空间中的全局变量 } voidmain(){ i=5;//文件作用域的i赋初值 Ns: : j=6;//为全局变量j赋值 {//子块1 usingnamespaceNs; inti;//局部变量,块作用域 i=7; cout<<”i="< cout<〈"j=”<〈j<〈endl; } cout〈〈”i=”〈 } 在主函数内子块1前,可引用到具有文件作用域的变量,它是可见的。 当进入子块1,只能引用到具有局部作用域的同名变量,文件作用域的同名变量不可见,称内层屏蔽,或同名覆盖,即内层的变量覆盖了外层的同名变量。 5.2对象的生存期P150 对象(包括简单变量)从诞生到结束的这段时间就是它的生存期. 5。 2。 1静态生存期 若对象的生存期与程序的运行期相同,称它具有静态生存期。 在文件作用域中声明的对象具有静态生存期的. 若要在函数内部的块作用域中声明具有静态生存期的对象,则要使用关键字static。 staticinti; i称为静态变量。 其余的对象都具有动态生存期. 定义时未指定初值的基本类型静态生存期变量,初值为0;动态生存期变量,不指定初值时值不确定. 5.2.2动态生存期 在块作用域中声明的具有动态生存期的对象,称局部生存期对象. 动态生存期对象诞生于声明点,结束于该标识符作用域结束处。 例5-2变量的生存期与可见性。 局部变量就是具有块作用域的变量. 全局变量就是具有文件作用域的变量。 #include〈iostream> usingnamespacestd; inti=1;//i为全局变量,具有静态生存期 voidother(void){ staticinta=2; staticintb;//a,b为静态局部变量,具有全局寿命,局部可见,只第一次进入函数时被初始化 intc=10;//c为局部变量,具有动态生存期,每次进入函数时都初始化 a=a+2;i=i+32;c=c+5; cout<〈”--—OTHER---\n”; cout〈<”i: "〈 "< "〈〈b<〈”c: "< b=a; } voidmain() { staticinta;//a为静态局部变量,具有全局寿命,局部可见 intb=—10;//b,c为局部变量,具有动态生存期 intc=0; cout<<"———MAIN--—\n”; cout〈<"i: ”〈 "〈〈a<<"b: "< "< c=c+8;other(); cout<<"——-MAIN——-\n"; cout<<"i: ”< ”〈〈a<<”b: ”<〈b<<”c: ”< c=c+10;other(); } 例5—3具有静态、动态生存期对象的时钟程序。 声明具有函数原型作用域、块作用域、类作用域和文件作用域的多个变量及对象,并分析各自的可见性和生存期。 #include〈iostream> usingnamespacestd; classClock//时钟类定义 { public: Clock(); voidsetTime(intnewH,intnewM,intnewS);//三个形参具有函数原型作用域 voidshowTime(); private: inthour,minute,second; }; //时钟类成员函数实现 Clock: : Clock(): hour(0),minute(0),second(0){}//构造函数 voidClock: : setTime(intnewH,intnewM,intnewS)//3个形参均具有局部作用域 {hour=newH;minute=newM;second=newS;} voidClock: : showTime(){cout<〈hour〈<”: ”〈〈minute〈<”: "〈〈second〈〈endl;} ClockglobClock;//声明对象,具有静态生存期,文件作用域 voidmain(){ cout<<"第一次输出: ”< //引用文件作用域的对象globClock : globClock.showTime();//对象的成员函数具有类作用域 globClock.setTime(8,30,30); ClockmyClock(globClock);//声明具有块作用域的对象 cout〈<”第二次输出: "〈 myClock.showTime();//引用具有块作用域的对象 } 5。 3类的静态成员P153 静态成员是解决同一个类的不同对象之间的数据和函数共享问题的. 例,抽象出某公司全体雇员的共性,设计如下的雇员类: classEmployee{//雇员类 private : intempNo ; intid ; stringname ;//字符串对象 。 。 。 } 若需要统计雇员总数,这个数据存放在什么地方呢? 若以类外的变量来存储总数,不能实现数据的隐藏。 若在类中增加一个数据成员用以存放总数,必然在每一个对象中都存储一个副本,不仅冗余,且每个对象分别维护一个“总数”,势必造成数据的不一致性。 比较理想的方案是类的所有对象共同拥有一个用于存放总数的数据成员. 5.3。 1静态数据成员P154 实例属性 “一个类的所有对象具有相同的属性”,是指属性的个数、名称、数据类型相同,各个对象的属性值则可各不相同。 以类的非静态数据成员表示。 类属性 是描述类的所有对象的共同特征的一个数据项,对于任何对象实例,它的属性值是相同的。 通过静态数据成员来实现“类属性”. 静态数据成员的访问 静态数据成员不属于任何一个对象,只能通过类名对它访问,用法是“类名: : 标识符”。 静态数据成员的说明和定义 在类的声明中仅仅对静态数据成员进行引用性说明,必须在文件作用域的某处用类名限定进行定义性说明,这时也可进行初始化. 在UML中,静态数据成员下方添加下划线. 例5-4具有静态数据成员的Point类. 引入静态数据成员的Point类。 图5—2包含静态数据成员的Point类的UML图 Point –x: int –y: int –count: int=0 +Point(xx: int=0,yy: int=0) +getX(): int +getY(): int +Point(p: Point&) +showCount(): void #include〈iostream〉 usingnamespacestd; classPoint//Point类定义 { public: Point(intxx=0,intyy=0): x(xx),y(yy){count++;}//所有对象共同维护count Point(Point&p){x=p。 x;y=p.y;count++;} ~Point(){count-—;} intgetX(){returnx;} intgetY(){returny;} voidshowCount(){cout<<”对象count=”< private: intx,y; staticintcount;//静态数据成员声明,用于记录点的个数 }; intPoint: : count=0;//静态数据成员定义和初始化,使用类名限定 voidmain() { Pointa(4,5);//定义对象a,其构造函数会使count增1 cout〈〈"Pointa: "<〈a。 getX()<〈","〈〈a。 getY(); a。 showCount();//输出对象个数 Pointb(a);//定义对象b,其拷贝构造函数会使count增1 cout〈〈"Pointb: ”〈〈b.getX()<〈","〈〈b。 getY(); b.showCount(); } 在对类的静态私有数据成员初始化的同时,还可引用类的其他私有成员。 例,若一个类T存在类型T的静态私有对象,则可引用该类的私有构造函数将其初始化。 5。 3。 2静态函数成员P156 静态成员函数是使用static关键字声明的函数成员。 静态成员函数属于整个类,由同一个类的所有对象共同维护,并共享。 对于公有的静态成员函数,可通过类名或对象名来调用. 静态成员函数可直接访问该类的静态数据和函数成员,而访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名来访问。 classA{ public: staticvoidf(Aa); private: intx; }; voidA: : f(Aa){ cout〈〈x;//对x的引用是错误的。 可用A: : f(c)调用,此时,无当前对象。 cout〈〈a.x;//正确 } 在UML中,静态函数成员前添加< 例5—5具有静态数据和函数成员的Point类。 图5—3包含静态函数成员的Point类的UML图 Point –x: int –y: int –count: int=0 +Point(xx: int=0,yy: int=0) +getX(): int +getY(): int +Point(p: Point&) <〈static〉>+showCount(): void #include〈iostream> usingnamespacestd; classPoint{ public: Point(intxx=0,intyy=0): x(xx),y(yy){count++;}; Point(Point&p){x=p。 x;y=p.y;count++;} ~Point(){count-—;} intgetX(){returnx;} intgetY(){returny;} staticvoidshowCount(){cout<〈"对象count="〈〈count〈〈endl;}//静态函数成员 private: intx,y; staticintcount;//静态数据成员声明 }; intPoint: : count=0;//静态数据成员定义及初始化,使用类名限定 voidmain() { Pointa(4,5); cout〈〈"Pointa:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 语言程序设计 实验 答案 数据 共享 保护 范本 模板