C++語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)答案-數(shù)據(jù)的共享與保護(hù)_第1頁(yè)
C++語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)答案-數(shù)據(jù)的共享與保護(hù)_第2頁(yè)
C++語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)答案-數(shù)據(jù)的共享與保護(hù)_第3頁(yè)
C++語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)答案-數(shù)據(jù)的共享與保護(hù)_第4頁(yè)
C++語(yǔ)言程序設(shè)計(jì)實(shí)驗(yàn)答案-數(shù)據(jù)的共享與保護(hù)_第5頁(yè)
已閱讀5頁(yè),還剩29頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、實(shí)驗(yàn)05 數(shù)據(jù)的共享與保護(hù)(2學(xué)時(shí))(第5章 數(shù)據(jù)的共享與保護(hù))一、實(shí)驗(yàn)?zāi)康?1) 觀察程序運(yùn)行中變量的作用域、生存期和可見性。(2) 學(xué)習(xí)類的靜態(tài)成員的使用。(3) 學(xué)習(xí)多文件結(jié)構(gòu)在C+程序中的使用。二、實(shí)驗(yàn)任務(wù)5_1 運(yùn)行下面的程序,觀察變量x、y的值。/lab5_1.cpp#include using namespace std;void fn1();int x=1,y=2;int main()cout開始.endl;coutx=xendl;couty=yendl;cout在main()中求x和y的值.endl;int x=10,y=20;coutx=xendl;couty=yendl;

2、 cout進(jìn)入函數(shù)fn1().endl;fn1();cout返回main()endl;coutx=xendl;couty=yendl; return 0;void fn1()int y=200;coutx=xendl;couty=yendl;5_2 實(shí)現(xiàn)客戶機(jī)(CLIENT)類。聲明字符型靜態(tài)數(shù)據(jù)成員ServerName,保存其服務(wù)器名稱;聲明整型靜態(tài)數(shù)據(jù)成員ClientNum,記錄已定義的客戶數(shù)量;定義靜態(tài)函數(shù)ChangeServerName()改變服務(wù)器名稱。在頭文件client.h中聲明類,在文件client.cpp中實(shí)現(xiàn),在文件lab5_2.cpp中測(cè)試這個(gè)類,觀察相應(yīng)的成員變量取值的

3、變化情況。三、實(shí)驗(yàn)步驟1.(驗(yàn)證)運(yùn)行l(wèi)ab5_1.cpp程序,觀察程序輸出。全局變量的作用域?yàn)槲募饔糜?,在整個(gè)程序運(yùn)行期間有效,但如果在局部模塊中聲明了同名的變量,則在局部模塊中,可見的是局部變量,此時(shí),全局變量不可見;而局部變量的生存期只限于相應(yīng)的程序模塊中,離開相應(yīng)的程序模塊,局部變量x、y就不再存在,此時(shí)同名的全局變量重新可見。程序名:lab5_1.cpp。 程序的運(yùn)行結(jié)果:2.(編程)實(shí)現(xiàn)客戶機(jī)(CLIENT)類。新建一個(gè)空的項(xiàng)目lab5_2,添加頭文件client.h,在其中聲明類CLIENT,注意使用編譯預(yù)處理命令;再添加源程序文件client.cpp,在其中實(shí)現(xiàn)CLIENT類

4、,注意靜態(tài)成員變量的使用方法;再添加文件lab5_2.cpp,在其中定義main()函數(shù),測(cè)試CLIENT類,觀察 相應(yīng)的成員變量取值的變化情況。提示:訪問一臺(tái)服務(wù)器的客戶總數(shù)。靜態(tài)成員為類的屬性,為所有的類的對(duì)象共同擁有。再定義兩個(gè)靜態(tài)成員函數(shù),分別顯示服務(wù)器名和客戶總數(shù)。構(gòu)造函數(shù)用于增加一個(gè)客戶,析構(gòu)函數(shù)用于減少一個(gè)客戶。定義一個(gè)對(duì)象,再定義第二個(gè)對(duì)象,然后減少一個(gè)對(duì)象。參考程序輸出結(jié)果: 程序及運(yùn)行結(jié)果:(1) 類聲明頭文件client.h/client.h#ifndef CLIENT_H#define CLIENT_H/其中的靜態(tài)成員為類的屬性,為所有的類的對(duì)象共同擁有class cl

5、ientpublic:client();client();static void ChangeServerName(char ss);/改變服務(wù)器名稱static void showServerName();static void showClientNum();private:static char ServerName;/保存服務(wù)器名,引用性說明static int ClientNum;/記錄已定義的客戶(即對(duì)象)數(shù)量,引用性說明;#endif(2) 類實(shí)現(xiàn)程序文件client.cpp/client.cpp#include #include client.husing namespace

6、std;client:client() ClientNum+;/增加一個(gè)對(duì)象(客戶)client:client() ClientNum-; /減少一個(gè)對(duì)象(客戶)void client:ChangeServerName(char sn) ServerName=sn; /無(wú)staticvoid client:showServerName() cout服務(wù)器名:ServerNameendl; void client:showClientNum() cout客戶總數(shù): ClientNum endl; /必須在文件作用域的某處用類名限定進(jìn)行定義性說明,這時(shí)也可以進(jìn)行初始化。char client:Se

7、rverName=A; /無(wú)staticint client:ClientNum=0;(3) 主函數(shù)文件lab5_2.cpp/lab5_2.cpp#include #include client.husing namespace std;void main()client:showServerName();/初始狀態(tài)client:showClientNum();/類名引用靜態(tài)成員函數(shù)client:ChangeServerName(B);client a;/增加一個(gè)客戶a. showServerName();/對(duì)象名引用靜態(tài)成員函數(shù)a. showClientNum();client b; /增加

8、一個(gè)客戶b. showServerName();b. showClientNum();/減少一個(gè)客戶client:showServerName();client:showClientNum();(4) 運(yùn)行結(jié)果附:第5章 數(shù)據(jù)的共享與保護(hù)5.1 標(biāo)識(shí)符的作用域與可見性P1465.1.1 作用域作用域是一個(gè)標(biāo)識(shí)符在程序正文中有效的區(qū)域。C+的作用域有:函數(shù)原型作用域、塊作用域(局部作用域)、類作用域、文件作用域。1. 函數(shù)原型作用域在函數(shù)原型聲明時(shí)形式參數(shù)的作用范圍。例, double Area(double radius);其中標(biāo)識(shí)符radius的作用(或稱有效)范圍在形參列表的左、右括號(hào)之間

9、,稱標(biāo)識(shí)符radius的作用域是函數(shù)原型作用域。由于在函數(shù)原型的形參表中起作用的只是形參類型,標(biāo)識(shí)符并不起作用,可省略。2. 局部作用域(塊作用域)例:void fun(int a)int b=a;cinb;if(b0)int c;.a的作用域c的作用域b的作用域形參作用域:從形參列表中的聲明處開始,到整個(gè)函數(shù)體結(jié)束處止。b和c都具有塊作用域,是不同的塊作用域。塊是一對(duì)大括號(hào)括起來(lái)的一段程序。此例,函數(shù)體是一個(gè)塊,if語(yǔ)句后的分支體又是一個(gè)較小的塊,二者是包含關(guān)系。在塊中聲明的標(biāo)識(shí)符,其作用域從聲明處開始,一直到塊結(jié)束的大括號(hào)為止。具有塊作用域的變量也稱為局部變量。3. 類作用域類是一組有名成

10、員的集合,類X的成員m具有類作用域,對(duì)m的訪問方式如下:(1) 若在X的成員函數(shù)中無(wú)同名的局部作用域標(biāo)識(shí)符,則在該函數(shù)內(nèi)可訪問成員m。(2) 通過表達(dá)式x.m或X:m。這正是程序中訪問對(duì)象成員的最基本方法。(3) 通過prt-m這樣的表達(dá)式,其中prt為指向X類的一個(gè)對(duì)象的指針。4. 命名空間作用域命名空間大型程序通常由不同模塊構(gòu)成,不同模塊中的類和函數(shù)之間可能發(fā)生重名,將引發(fā)錯(cuò)誤。命名空間可以解決類名、函數(shù)等的命名沖突。命名空間語(yǔ)法形式:namespace 命名空間名命名空間內(nèi)的各種聲明(函數(shù)聲明、類聲明、)例namespace SomeNs class SomeClass . ;特殊的命名

11、空間_ 全局命名空間:默認(rèn)的命名空間_ 匿名命名空間:對(duì)每個(gè)源文件是唯一的命名空間作用域一個(gè)命名空間確定了一個(gè)命名空間作用域引用其它命名空間作用域中的標(biāo)識(shí)符_ 命名空間名:標(biāo)識(shí)符名_ 例:聲明一個(gè)SomeClass型的對(duì)象SomeNs:SomeClass obj1;將其它命名空間作用域的標(biāo)識(shí)符暴露于當(dāng)前作用域_ 對(duì)指定標(biāo)識(shí)符using 命名空間名:標(biāo)識(shí)符名;_ 對(duì)所有標(biāo)識(shí)符using namespace命名空間名;例5-1中所聲明的全局變量就具有文件作用域,它們?cè)谡麄€(gè)文件中都有效。例5-1 作用域?qū)嵗?include using namespace std; /使得在當(dāng)前文件中可直接引用st

12、d命名空間的標(biāo)識(shí)符coutint i;/全局變量,文件作用域namespace Nsint j;/在Ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值Ns:j=6;/為全局變量j賦值/子塊1using namespace Ns;/使得在當(dāng)前塊中可直接引用Ns命名空間的標(biāo)識(shí)符int i;/局部變量,塊作用域i=7;couti=iendl;/輸出7coutj=jendl;couti=iendl;/輸出5參考(cout, endl是命名空間std中的全局變量):#include /using namespace std; /使得在當(dāng)前文件中可直接引用std命名空間的標(biāo)識(shí)符c

13、out,endlint i;/全局變量,文件作用域namespace Nsint j;/在Ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值Ns:j=6;/為全局變量j賦值/子塊1using namespace Ns;/使得在當(dāng)前塊中可直接引用Ns命名空間的標(biāo)識(shí)符int i;/局部變量,塊作用域i=7;std:couti=i std:endl;/輸出7std:coutj=j std:endl;std:couti=i std:endl;/輸出5具有文件作用域的變量也稱為全局變量。5.1.2 可見性P150可見的標(biāo)識(shí)符 程序運(yùn)行到某一點(diǎn),能夠引用到的標(biāo)識(shí)符。文件作用域最大

14、,接下來(lái)依次是類作用域和塊作用域。圖5-1 作用域關(guān)系圖可見性表示從內(nèi)層作用域向外層作用域“看”時(shí)能看到什么。作用域可見性的一般規(guī)則:_ 標(biāo)識(shí)符聲明在前,引用在后。_ 同一作用域,不能聲明同名標(biāo)識(shí)符。_ 在沒有包含關(guān)系的不同作用域中聲明的同名標(biāo)識(shí)符互不影響。_ 在具有包含關(guān)系的作用域中聲明了同名標(biāo)識(shí)符,則外層標(biāo)識(shí)符在內(nèi)層不可見。例5-l中,文件作用域與塊作用域相互包含。#include using namespace std;int i;/全局變量,文件作用域namespace Nsint j;/在Ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值Ns:j=6;/為全

15、局變量j賦值/子塊1using namespace Ns;int i;/局部變量,塊作用域i=7;couti=iendl;/輸出7coutj=jendl;couti=iendl;/輸出5在主函數(shù)內(nèi)子塊1前,可引用到具有文件作用域的變量,它是可見的。當(dāng)進(jìn)入子塊1,只能引用到具有局部作用域的同名變量,文件作用域的同名變量不可見,稱內(nèi)層屏蔽,或同名覆蓋,即內(nèi)層的變量覆蓋了外層的同名變量。5.2 對(duì)象的生存期P150對(duì)象(包括簡(jiǎn)單變量)從誕生到結(jié)束的這段時(shí)間就是它的生存期。5.2.1 靜態(tài)生存期若對(duì)象的生存期與程序的運(yùn)行期相同,稱它具有靜態(tài)生存期。在文件作用域中聲明的對(duì)象具有靜態(tài)生存期的。若要在函數(shù)內(nèi)

16、部的塊作用域中聲明具有靜態(tài)生存期的對(duì)象,則要使用關(guān)鍵字static。 static int i;i稱為靜態(tài)變量。其余的對(duì)象都具有動(dòng)態(tài)生存期。定義時(shí)未指定初值的基本類型靜態(tài)生存期變量,初值為0;動(dòng)態(tài)生存期變量,不指定初值時(shí)值不確定。5.2.2 動(dòng)態(tài)生存期在塊作用域中聲明的具有動(dòng)態(tài)生存期的對(duì)象,稱局部生存期對(duì)象。動(dòng)態(tài)生存期對(duì)象誕生于聲明點(diǎn),結(jié)束于該標(biāo)識(shí)符作用域結(jié)束處。例5-2 變量的生存期與可見性。局部變量就是具有塊作用域的變量。全局變量就是具有文件作用域的變量。#include using namespace std;int i=1;/i為全局變量,具有靜態(tài)生存期void other(void)

17、static int a=2;static int b;/a, b為靜態(tài)局部變量,具有全局壽命,局部可見,只第一次進(jìn)入函數(shù)時(shí)被初始化int c=10;/c為局部變量,具有動(dòng)態(tài)生存期,每次進(jìn)入函數(shù)時(shí)都初始化a=a+2; i=i+32; c=c+5;cout-OTHER-n;couti:i a:a b:b c:cendl;b=a;void main()static int a;/a為靜態(tài)局部變量,具有全局壽命,局部可見int b=-10;/b, c為局部變量,具有動(dòng)態(tài)生存期int c=0;cout-MAIN-n;couti:i a:a b:b c:cendl;c=c+8; other();cout

18、-MAIN-n;couti:i a:a b:b c:cendl;c=c+10; other();例5-3 具有靜態(tài)、動(dòng)態(tài)生存期對(duì)象的時(shí)鐘程序。聲明具有函數(shù)原型作用域、塊作用域、類作用域和文件作用域的多個(gè)變量及對(duì)象,并分析各自的可見性和生存期。#include using namespace std;class Clock/時(shí)鐘類定義public:Clock();void setTime(int newH,int newM,int newS);/三個(gè)形參具有函數(shù)原型作用域void showTime();private:int hour,minute,second;/時(shí)鐘類成員函數(shù)實(shí)現(xiàn)Clock:

19、Clock():hour(0),minute(0),second(0) /構(gòu)造函數(shù)void Clock:setTime(int newH,int newM,int newS)/3個(gè)形參均具有局部作用域 hour=newH; minute=newM; second=newS; void Clock:showTime() couthour:minute:secondendl;Clock globClock;/聲明對(duì)象,具有靜態(tài)生存期,文件作用域void main()cout第一次輸出:endl;/引用文件作用域的對(duì)象globClock:globClock.showTime();/對(duì)象的成員函數(shù)具有

20、類作用域globClock.setTime(8,30,30);Clock myClock(globClock);/聲明具有塊作用域的對(duì)象cout第二次輸出:endl;myClock.showTime();/引用具有塊作用域的對(duì)象5.3 類的靜態(tài)成員P153靜態(tài)成員是解決同一個(gè)類的不同對(duì)象之間的數(shù)據(jù)和函數(shù)共享問題的。例,抽象出某公司全體雇員的共性,設(shè)計(jì)如下的雇員類:class Employee/雇員類private:int empNo;int id;string name;/字符串對(duì)象.若需要統(tǒng)計(jì)雇員總數(shù),這個(gè)數(shù)據(jù)存放在什么地方呢?若以類外的變量來(lái)存儲(chǔ)總數(shù),不能實(shí)現(xiàn)數(shù)據(jù)的隱藏。若在類中增加一個(gè)數(shù)

21、據(jù)成員用以存放總數(shù),必然在每一個(gè)對(duì)象中都存儲(chǔ)一個(gè)副本,不僅冗余,且每個(gè)對(duì)象分別維護(hù)一個(gè)“總數(shù)”,勢(shì)必造成數(shù)據(jù)的不一致性。比較理想的方案是類的所有對(duì)象共同擁有一個(gè)用于存放總數(shù)的數(shù)據(jù)成員。5.3.1 靜態(tài)數(shù)據(jù)成員P154實(shí)例屬性“一個(gè)類的所有對(duì)象具有相同的屬性”,是指屬性的個(gè)數(shù)、名稱、數(shù)據(jù)類型相同,各個(gè)對(duì)象的屬性值則可各不相同。以類的非靜態(tài)數(shù)據(jù)成員表示。類屬性是描述類的所有對(duì)象的共同特征的一個(gè)數(shù)據(jù)項(xiàng),對(duì)于任何對(duì)象實(shí)例,它的屬性值是相同的。通過靜態(tài)數(shù)據(jù)成員來(lái)實(shí)現(xiàn)“類屬性”。靜態(tài)數(shù)據(jù)成員的訪問靜態(tài)數(shù)據(jù)成員不屬于任何一個(gè)對(duì)象,只能通過類名對(duì)它訪問,用法是“類名:標(biāo)識(shí)符”。靜態(tài)數(shù)據(jù)成員的說明和定義在類的聲

22、明中僅僅對(duì)靜態(tài)數(shù)據(jù)成員進(jìn)行引用性說明,必須在文件作用域的某處用類名限定進(jìn)行定義性說明,這時(shí)也可進(jìn)行初始化。在UML中,靜態(tài)數(shù)據(jù)成員下方添加下劃線。例5-4 具有靜態(tài)數(shù)據(jù)成員的Point類。引入靜態(tài)數(shù)據(jù)成員的Point類。圖5-2 包含靜態(tài)數(shù)據(jù)成員的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 using namespace std;class Po

23、int/Point類定義public:Point(int xx=0,int yy=0):x(xx),y(yy) count+; /所有對(duì)象共同維護(hù)countPoint(Point &p) x=p.x; y=p.y; count+; Point() count-; int getX() return x; int getY() return y; void showCount() cout 對(duì)象count=countendl; /輸出靜態(tài)數(shù)據(jù)成員private:int x,y;static int count;/靜態(tài)數(shù)據(jù)成員聲明,用于記錄點(diǎn)的個(gè)數(shù);int Point:count=0;/靜態(tài)數(shù)據(jù)成

24、員定義和初始化,使用類名限定void main()Point a(4,5);/定義對(duì)象a,其構(gòu)造函數(shù)會(huì)使count增1coutPoint a: a.getX(),a.getY();a.showCount();/輸出對(duì)象個(gè)數(shù)Point b(a); /定義對(duì)象b,其拷貝構(gòu)造函數(shù)會(huì)使count增1coutPoint b: b.getX(),b.getY();b.showCount();在對(duì)類的靜態(tài)私有數(shù)據(jù)成員初始化的同時(shí),還可引用類的其他私有成員。例,若一個(gè)類T存在類型T的靜態(tài)私有對(duì)象,則可引用該類的私有構(gòu)造函數(shù)將其初始化。5.3.2 靜態(tài)函數(shù)成員P156靜態(tài)成員函數(shù)是使用static關(guān)鍵字聲明的函

25、數(shù)成員。靜態(tài)成員函數(shù)屬于整個(gè)類,由同一個(gè)類的所有對(duì)象共同維護(hù),并共享。對(duì)于公有的靜態(tài)成員函數(shù),可通過類名或?qū)ο竺麃?lái)調(diào)用。靜態(tài)成員函數(shù)可直接訪問該類的靜態(tài)數(shù)據(jù)和函數(shù)成員,而訪問非靜態(tài)數(shù)據(jù)成員,必須通過參數(shù)傳遞方式得到對(duì)象名,然后通過對(duì)象名來(lái)訪問。class Apublic:static void f(A a);private:int x;void A:f(A a)coutx;/對(duì)x的引用是錯(cuò)誤的??捎肁:f(c)調(diào)用,此時(shí),無(wú)當(dāng)前對(duì)象。couta.x;/正確在UML中,靜態(tài)函數(shù)成員前添加。例5-5 具有靜態(tài)數(shù)據(jù)和函數(shù)成員的Point類。圖5-3 包含靜態(tài)函數(shù)成員的Point類的UML圖Point

26、 x : int y : int count : int=0+Point(xx : int=0, yy : int=0)+getX() : int+getY() : int+Point(p : Point&)+showCount() : void#include using namespace std;class Pointpublic:Point(int xx=0,int yy=0):x(xx),y(yy) count+; ;Point(Point &p) x=p.x; y=p.y; count+; Point() count-; int getX() return x; int getY(

27、) return y; static void showCount() cout 對(duì)象count=countendl; /靜態(tài)函數(shù)成員private:int x,y;static int count;/靜態(tài)數(shù)據(jù)成員聲明;int Point:count=0;/靜態(tài)數(shù)據(jù)成員定義及初始化,使用類名限定void main()Point a(4,5);coutPoint a: a.getX(),a.getY();Point:showCount();/輸出對(duì)象號(hào),類名引用Point b(a);coutPoint b: b.getX(),b.getY();b.showCount();/輸出對(duì)象號(hào),對(duì)象名引用

28、采用靜態(tài)函數(shù)成員的好處可不依賴于任何對(duì)象,直接訪問靜態(tài)數(shù)據(jù)。5.4 類的友元P158友元提供了不同類或?qū)ο蟮某蓡T函數(shù)之間、類的成員函數(shù)與一般函數(shù)之間進(jìn)行數(shù)據(jù)共享的機(jī)制。在一個(gè)類中,可用關(guān)鍵字friend將其他函數(shù)或類聲明為友元。若友元是一般函數(shù)或類的成員函數(shù),稱友元函數(shù);若友元是一個(gè)類,稱友元類,友元類的所有成員函數(shù)都自動(dòng)成為友元函數(shù)。5.4.1 友元函數(shù)P160友元函數(shù)是在類中用關(guān)鍵字friend修飾的非成員函數(shù)。友元函數(shù)不是本類的成員函數(shù),但是在它的函數(shù)體中可通過對(duì)象名訪問類的私有和保護(hù)成員。在UML中,友元函數(shù)前添加。例5-6 使用友元函數(shù)計(jì)算兩點(diǎn)間的距離。圖5-4 包含友元函數(shù)成員的P

29、oint類的UML圖Point x : int y : int+Point(xx : int=0, yy : int=0)+getX() : int+getY() : int+dist(a : Point&, b : Point&) : foat#include #include using namespace std;class Point/Point類定義public:Point(int xx=0,int yy=0):x(xx),y(yy)int getX() return x; int getY() return y; friend float dist(Point &p1,Point

30、&p2);/友元函數(shù)聲明private:int x,y;float dist(Point &p1,Point &p2)/友元函數(shù)實(shí)現(xiàn)double x=double(p1.x-p2.x);/通過對(duì)象訪問私有數(shù)據(jù)成員double y=double(p1.y-p2.y);return static_cast(sqrt(x*x+y*y);void main()Point myp1(1,1),myp2(4,5);cout距離是:;coutdist(myp1,myp2)endl;5.4.2 友元類P161若A類為B類的友元類,則A類的所有成員函數(shù)都是B類的友元函數(shù),都可以訪問B類的私有和保護(hù)成員。clas

31、s B. /B類的成員聲明friend class A;/聲明A為B的友元類.;聲明友元類,是建立類與類之間的聯(lián)系,實(shí)現(xiàn)類之間數(shù)據(jù)共享的一種途徑。在UML中,兩個(gè)類之間的友元關(guān)系是通過構(gòu)造型依賴來(lái)表征。圖5-5 類A和類B友元關(guān)系的UML圖B+set(i : int) : void+display() : voidA x : int+display() : void+getx() : int-a#include using namespace std;class Apublic:void display() coutxendl; int getx() return x; friend clas

32、s B;private:int x;class Bpublic:void set(int i);void display() couta.xendl; private:A a;void B:set(int i)a.x=i;/由于B是A的友元,所以在B的成員函數(shù)中可以訪問A類對(duì)象的私有成員void main()B b;b.set(5);b.display();注意:第一,友元關(guān)系是不能傳遞的。第二,友元關(guān)系是單向。第三,友元關(guān)系是不被繼承的。5.5 共享數(shù)據(jù)的保護(hù)P1635.5.1 常對(duì)象聲明格式:const 類型說明符 對(duì)象名;或類型說明符 const 對(duì)象名;常對(duì)象必須進(jìn)行初始化,且不能被更

33、新。語(yǔ)法如何保障常對(duì)象的值不被改變呢?改變對(duì)象的數(shù)據(jù)成員值有兩個(gè)途徑:一是在類外通過對(duì)象名訪問其公有數(shù)據(jù)成員,這時(shí)語(yǔ)法會(huì)限制不能再賦值。二是在類的成員函數(shù)中改變數(shù)據(jù)成員的值,規(guī)定不能通過常對(duì)象調(diào)用普通的成員函數(shù)。5.5.2 用const修飾的類成員P1641. 常成員函數(shù)聲明格式:類型說明符 函數(shù)(參數(shù)表)const;注意: const是函數(shù)類型的一個(gè)組成部分。 常成員函數(shù)不能更新對(duì)象的數(shù)據(jù)成員,也不能調(diào)用該類中沒有用const修飾的成員函數(shù)。 常對(duì)象只能調(diào)用它的常成員函數(shù)。 const可用于對(duì)重載函數(shù)的區(qū)分。例如, void print(); void print() const;這是對(duì)pr

34、int的有效重載。在UML中,常成員函數(shù)前添加。例5-7 常成員函數(shù)舉例。圖5-6 包含常成員函數(shù)的R類的UML圖R r1 : int r2 : int+R(rr1 : int, rr2 : int)+print() : void+print() : void#include using namespace std;class Rpublic:R(int rr1,int rr2):r1(rr1),r2(rr2)void print();void print() const;/常成員函數(shù)private:int r1,r2;void R:print() coutr1:r2endl; void R:

35、print() const coutr1;r2endl; void main()R a(5,4);a.print();const R b(20,52);b.print();2. 常數(shù)據(jù)成員類的成員數(shù)據(jù)也可以是常量。使用const說明的數(shù)據(jù)成員為常數(shù)據(jù)成員。任何函數(shù)中都不能對(duì)常數(shù)據(jù)成員賦值。構(gòu)造函數(shù)對(duì)常數(shù)據(jù)成員進(jìn)行初始化,就只能通過初始化列表。在UML中,常數(shù)據(jù)成員前添加const。例5-8 常數(shù)據(jù)成員舉例。圖5-7 包含常數(shù)據(jù)成員的A類的UML圖A a : const int b : const int=10+A(i : int)+print() : void#include using na

36、mespace std;class Apublic:A(int i);void print();private:const int a;/常數(shù)據(jù)成員static const int b;/靜態(tài)常數(shù)據(jù)成員;const int A:b=10;/靜態(tài)常數(shù)據(jù)成員在類外說明和初始化A:A(int i):a(i) /常數(shù)據(jù)成員只能通過初始化列表來(lái)獲得初值 void A:print() couta:bendl; void main()/*建立對(duì)象a1和a2,并以100和0作為初值,分別調(diào)用構(gòu)造函數(shù),通過構(gòu)造函數(shù)的初始化列表給對(duì)象的常數(shù)據(jù)成員賦初值*/A a1(100),a2(0);a1.print();a2

37、.print();5.5.3 常引用P166常引用的說明形式:const 類型說明符 &引用名;常引用所引用的對(duì)象不能被更新。若用常引用做形參,便不會(huì)發(fā)生對(duì)實(shí)參意外的更改。例5-9 常引用做形參#include #include using namespace std;class Point/Point類定義public:Point(int xx=0,int yy=0):x(xx),y(yy)int getX() return x; int getY() return y; friend float dist(const Point &p1,const Point &p2);/友元函數(shù)聲明pr

38、ivate:int x,y;float dist(const Point &p1, const Point &p2)/友元函數(shù)實(shí)現(xiàn)double x=double(p1.x-p2.x);/通過對(duì)象訪問私有數(shù)據(jù)成員double y=double(p1.y-p2.y);return static_cast(sqrt(x*x+y*y);void main()const Point myp1(1,1),myp2(4,5);cout距離是:;coutdist(myp1,myp2)endl;*5.6 多文件結(jié)構(gòu)和編譯預(yù)處理命令P1685.6.1 C+程序的一般組織結(jié)構(gòu)通常一個(gè)項(xiàng)目至少劃分為三個(gè)文件:類聲明文

39、件(*.h文件)類實(shí)現(xiàn)文件(*.cpp文件)類的使用文件(*.cpp,主函數(shù)文件)每個(gè)源程序文件稱為一個(gè)編譯單元。C+語(yǔ)法要求一個(gè)類的聲明必須出現(xiàn)在所有使用該類的編譯單元中。慣用的做法將類的聲明寫在頭文件中,使用該類的編譯單元?jiǎng)t包含這個(gè)頭文件。例5-10 具有靜態(tài)數(shù)據(jù)、函數(shù)成員的Point類,多文件組織。/文件1,類的聲明,point.h#include using namespace std;class Pointpublic:Point(int xx=0,int yy=0)X=xx; Y=yy; countP+; ;Point(Point &p);Point()countP-;int Ge

40、tX()return X;int GetY()return Y;static void GetC() cout對(duì)象id=countPendl; /靜態(tài)函數(shù)成員private:int X,Y;static int countP;/靜態(tài)數(shù)據(jù)成員聲明;/文件2,類的實(shí)現(xiàn),point.cpp#include “point.h”int Point:countP=0;/靜態(tài)數(shù)據(jù)成員定義及初始化,使用類名限定Point:Point(Point &p) X=p.X; Y=p.Y; countP+; /文件3,主函數(shù),pmain.cpp#include “point.h”void main()Point A(4

41、,5);coutPoint A,A.GetX(),A.GetY();A.GetC();/輸出對(duì)象號(hào),對(duì)象名引用Point B(A);coutPoint B,B.GetX(),B.GetY();Point:GetC();/輸出對(duì)象號(hào),類名引用圖5-8 C+多文件組織結(jié)構(gòu)圖#include指令的作用將指定的源文件嵌入到當(dāng)前源文件中#include指令所在位置,被嵌入的文件可以是.h文件,也可以是.cpp文件。#include兩上書寫方式#include,按照標(biāo)準(zhǔn)方式搜索要嵌入的文件,該文件位于C+系統(tǒng)目錄的include子目錄下,一般包含系統(tǒng)提供的標(biāo)準(zhǔn)文件時(shí)采用這樣的方式。#include文件名,

42、首先在當(dāng)前目錄下搜索要嵌入的文件,若沒有,再按照標(biāo)準(zhǔn)方式搜索,對(duì)用戶自己編寫的文件一般采用這種方式。在使用多文件結(jié)構(gòu)時(shí),注意內(nèi)聯(lián)函數(shù)的特殊性一個(gè)內(nèi)聯(lián)函數(shù),需要在每個(gè)調(diào)用它的編譯單元中給出一個(gè)完全一致的實(shí)現(xiàn)。慣用的做法是將內(nèi)聯(lián)函數(shù)的實(shí)現(xiàn)寫在頭文件中,由調(diào)用的編譯單元包含這個(gè)頭文件。5.6.2 外部變量與外部函數(shù)P170用extern聲明外部變量。外部變量是具有文件作用域的變量,定義在所有文件之外。聲明一個(gè)外部變量時(shí),可以同時(shí)定義它,也可以只是引用一個(gè)在別處聲明的外部變量。/源文件1int i=3;/定義變量ivoid next(void);/函數(shù)原型聲明void main() i+; next(

43、); void next(void) i+; other(); /源文件2extern int i;/聲明一個(gè)在其他文件中定義的外部變量ivoid other(void) i+; 外部變量是可以為多個(gè)源文件所共享的全局變量。定義性聲明 引用性聲明對(duì)外部變量的聲明可以是定義性聲明,即在聲明的同時(shí)定義(分配內(nèi)存,初始化),也可以是引用性聲明(引用在別處定義的變量)。外部變量可用extern在多處聲明,但對(duì)變量的定義和初始化是惟一的。定義一個(gè)文件作用域的變量時(shí),其默認(rèn)狀態(tài)可以為不同的編譯單元所共享,只要在其他編譯單元中冠以extern聲明該變量即可,若在文件作用域中定義變量時(shí)以static修飾,則該

44、變量的作用范圍僅限于定義它的編譯單元。2. 外部函數(shù)非成員函數(shù)具有文件作用域,可以在不同的編譯單元被調(diào)用,只要在調(diào)用之前聲明函數(shù)原型即可??梢栽诼暶骱瘮?shù)原型或定義函數(shù)時(shí)用extern修飾,其效果與不加修飾的默認(rèn)狀態(tài)是一樣的。若在聲明一個(gè)函數(shù)原型時(shí)或定義函數(shù)時(shí)冠以static修飾,就將函數(shù)的作用域限制在當(dāng)前的編譯單元內(nèi)。5.6.3 標(biāo)準(zhǔn)C+庫(kù)P172標(biāo)準(zhǔn)C+類與組件在邏輯上分為6種類型:輸入/輸出類容器類與ADT(抽象數(shù)據(jù)類型)存儲(chǔ)管理類算法錯(cuò)誤處理運(yùn)行環(huán)境支持對(duì)庫(kù)中預(yù)定義內(nèi)容的說明分別存在于不同的頭文件中,要使用這些預(yù)定義的成分,就要將相應(yīng)的頭文件包含到源程序中。標(biāo)準(zhǔn)C+庫(kù)不再有“.h”擴(kuò)展名

45、,但仍保留18個(gè)帶有“.h”擴(kuò)展名的C頭文件。兩種形式的頭文件不能混用。比如,若已經(jīng)包含頭文件iostream,就不能再包含math.h,而要代之以新的頭文件cmath。使用標(biāo)準(zhǔn)C+庫(kù)時(shí),在緊接著所有的include指令之后,加入using namespace std;將指定命名空間中的名稱引入到當(dāng)前命名空間中。否則,需要在使用std命名空間中的標(biāo)識(shí)符時(shí)冠以命名空間名“:”。(第10章)5.6.4 編譯預(yù)處理P173編譯器在對(duì)源程序進(jìn)行編譯之前,首先要由預(yù)處理程序?qū)Τ绦蛭谋具M(jìn)行預(yù)處理。預(yù)處理程序提供了一組編譯預(yù)處理指令和預(yù)處理操作符。所有的預(yù)處理指令在程序中都是以“#”來(lái)引導(dǎo),每一條預(yù)處理指令

46、單獨(dú)占用行,不要用分號(hào)結(jié)束。預(yù)處理指令可以根據(jù)需要出現(xiàn)在程序中的任何位置。1. #include指令(文件包含指令)其作用是將另一個(gè)源文件嵌入到當(dāng)前源文件中該點(diǎn)處。 include按標(biāo)準(zhǔn)方式搜索,文件位于C+系統(tǒng)目錄的include子目錄下。 include文件名首先在當(dāng)前目錄中搜索,若沒有,再按標(biāo)準(zhǔn)方式控索。2. #define和#undef指令#define用來(lái)定義符號(hào)常量,例如,#define PI 3.14。#undef用來(lái)刪除由#define定義的宏,使之不再起作用。3. 條件編譯指令用來(lái)限定程序中的某些內(nèi)容要在滿足一定條件的情況下才參與編譯。常用的條件編譯語(yǔ)句有下列5種形式: 形式

47、1#if 常量表達(dá)式程序段 /當(dāng)“常量表達(dá)式”非0時(shí)編譯本程序段#endif 形式2#if 常量表達(dá)式程序段1 /當(dāng)“常量表達(dá)式”非0時(shí)編譯本程序段#else程序段2 /當(dāng)“常量表達(dá)式”為0時(shí)編譯本程序段#endif 形式3#if 常量表達(dá)式1程序段1 /當(dāng)“常量表達(dá)式1”非0時(shí)編譯本程序段#elif常量表達(dá)式2程序段2 /否則,當(dāng)“常量表達(dá)式2”非0時(shí)編譯本程序段 .#elif常量表達(dá)式n程序段n /否則,當(dāng)“常量表達(dá)式n”非0時(shí)編譯本程序段#else程序段n+1 /其他情況下編譯本程序段#endif 形式4#ifdef 標(biāo)識(shí)符程序段1 /若“標(biāo)識(shí)符”經(jīng)#define定義過,且未經(jīng)#unde

48、f刪除,則編譯本程序段#else程序段2 /否則編譯本程序段#endif#ifdef 標(biāo)識(shí)符程序段 /若“標(biāo)識(shí)符”經(jīng)#define定義過,且未經(jīng)#undef刪除,則編譯本程序段#endif 形式5#ifndef 標(biāo)識(shí)符程序段1 /若“標(biāo)識(shí)符”未定義過,則編譯本程序段#else程序段2 /否則編譯本程序段#endif#ifdef 標(biāo)識(shí)符程序段 /若“標(biāo)識(shí)符”未定義過,則編譯本程序段#endif4. defined操作符defined是一個(gè)預(yù)處理操作符,而不是指令,因此不要以#開頭。defined(標(biāo)識(shí)符)若“標(biāo)識(shí)符”在此前經(jīng)#define定義過,且未經(jīng)#undef刪除,則上述表達(dá)式為非0,否則為0。下面兩種寫法是完全等效的:#ifndef MYHEAD_H#define MYHEAD_H.#endif#if !define(MYHEAD_H)#define MYHEAD_H.#endif由于文件包含指令可以嵌套使用,在設(shè)計(jì)程序時(shí)要避免多次重復(fù)包含同一個(gè)頭文件,否則會(huì)引起變量及類的重復(fù)定義。例,某個(gè)工程包括如下四個(gè)源文件。/main.cpp#include “file1.h”#include “file2.h”void main()

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論