C++語言程序設計實驗答案_數(shù)據(jù)的共享與保護_第1頁
C++語言程序設計實驗答案_數(shù)據(jù)的共享與保護_第2頁
C++語言程序設計實驗答案_數(shù)據(jù)的共享與保護_第3頁
C++語言程序設計實驗答案_數(shù)據(jù)的共享與保護_第4頁
C++語言程序設計實驗答案_數(shù)據(jù)的共享與保護_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

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

2、;endl;cout<<"y="<<y<<endl;cout<<"在main()中求x和y的值."<<endl;int x=10,y=20;cout<<"x="<<x<<endl;cout<<"y="<<y<<endl; cout<<"進入函數(shù)fn1()."<<endl;fn1();cout<<"返回main()&quo

3、t;<<endl;cout<<"x="<<x<<endl;cout<<"y="<<y<<endl; return 0;void fn1()int y=200;cout<<"x="<<x<<endl;cout<<"y="<<y<<endl;5_2 實現(xiàn)客戶機(client)類。聲明字符型靜態(tài)數(shù)據(jù)成員servername,保存其服務器名稱;聲明整型靜態(tài)數(shù)據(jù)成員cli

4、entnum,記錄已定義的客戶數(shù)量;定義靜態(tài)函數(shù)changeservername()改變服務器名稱。在頭文件client.h中聲明類,在文件client.cpp中實現(xiàn),在文件lab5_2.cpp中測試這個類,觀察相應的成員變量取值的變化情況。三、實驗步驟1.(驗證)運行l(wèi)ab5_1.cpp程序,觀察程序輸出。全局變量的作用域為文件作用域,在整個程序運行期間有效,但如果在局部模塊中聲明了同名的變量,則在局部模塊中,可見的是局部變量,此時,全局變量不可見;而局部變量的生存期只限于相應的程序模塊中,離開相應的程序模塊,局部變量x、y就不再存在,此時同名的全局變量重新可見。程序名:lab5_1.cpp

5、。 程序的運行結(jié)果:2.(編程)實現(xiàn)客戶機(client)類。新建一個空的項目lab5_2,添加頭文件client.h,在其中聲明類client,注意使用編譯預處理命令;再添加源程序文件client.cpp,在其中實現(xiàn)client類,注意靜態(tài)成員變量的使用方法;再添加文件lab5_2.cpp,在其中定義main()函數(shù),測試client類,觀察 相應的成員變量取值的變化情況。提示:訪問一臺服務器的客戶總數(shù)。靜態(tài)成員為類的屬性,為所有的類的對象共同擁有。再定義兩個靜態(tài)成員函數(shù),分別顯示服務器名和客戶總數(shù)。構(gòu)造函數(shù)用于增加一個客戶,析構(gòu)函數(shù)用于減少一個客戶。定義一個對象,再定義第二個對象,然后減少

6、一個對象。參考程序輸出結(jié)果: 程序及運行結(jié)果:(1) 類聲明頭文件client.h/client.h#ifndef client_h#define client_h/其中的靜態(tài)成員為類的屬性,為所有的類的對象共同擁有class clientpublic:client();client();static void changeservername(char ss);/改變服務器名稱static void showservername();static void showclientnum();private:static char servername;/保存服務器名,引用性說明static i

7、nt clientnum;/記錄已定義的客戶(即對象)數(shù)量,引用性說明;#endif(2) 類實現(xiàn)程序文件client.cpp/client.cpp#include <iostream>#include "client.h"using namespace std;client:client() clientnum+;/增加一個對象(客戶)client:client() clientnum-; /減少一個對象(客戶)void client:changeservername(char sn) servername=sn; /無staticvoid client:sh

8、owservername() cout<<"服務器名:"<<servername<<endl; void client:showclientnum() cout<<"客戶總數(shù):"<< clientnum <<endl; /必須在文件作用域的某處用類名限定進行定義性說明,這時也可以進行初始化。char client:servername='a' /無staticint client:clientnum=0;(3) 主函數(shù)文件lab5_2.cpp/lab5_2.cpp#i

9、nclude <iostream>#include "client.h"using namespace std;void main()client:showservername();/初始狀態(tài)client:showclientnum();/類名引用靜態(tài)成員函數(shù)client:changeservername('b');client a;/增加一個客戶a. showservername();/對象名引用靜態(tài)成員函數(shù)a. showclientnum();client b; /增加一個客戶b. showservername();b. showclient

10、num();/減少一個客戶client:showservername();client:showclientnum();(4) 運行結(jié)果附:第5章 數(shù)據(jù)的共享與保護5.1 標識符的作用域與可見性p1465.1.1 作用域作用域是一個標識符在程序正文中有效的區(qū)域。c+的作用域有:函數(shù)原型作用域、塊作用域(局部作用域)、類作用域、文件作用域。1. 函數(shù)原型作用域在函數(shù)原型聲明時形式參數(shù)的作用范圍。例, double area(double radius);其中標識符radius的作用(或稱有效)范圍在形參列表的左、右括號之間,稱標識符radius的作用域是函數(shù)原型作用域。由于在函數(shù)原型的形參表中起

11、作用的只是形參類型,標識符并不起作用,可省略。2. 局部作用域(塊作用域)例:void fun(int a)int b=a;cin>>b;if(b>0)int c;.a的作用域c的作用域b的作用域形參作用域:從形參列表中的聲明處開始,到整個函數(shù)體結(jié)束處止。b和c都具有塊作用域,是不同的塊作用域。塊是一對大括號括起來的一段程序。此例,函數(shù)體是一個塊,if語句后的分支體又是一個較小的塊,二者是包含關(guān)系。在塊中聲明的標識符,其作用域從聲明處開始,一直到塊結(jié)束的大括號為止。具有塊作用域的變量也稱為局部變量。3. 類作用域類是一組有名成員的集合,類x的成員m具有類作用域,對m的訪問方式

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

13、名命名空間:對每個源文件是唯一的命名空間作用域一個命名空間確定了一個命名空間作用域引用其它命名空間作用域中的標識符_ 命名空間名:標識符名_ 例:聲明一個someclass型的對象somens:someclass obj1;將其它命名空間作用域的標識符暴露于當前作用域_ 對指定標識符using 命名空間名:標識符名;_ 對所有標識符using namespace命名空間名;例5-1中所聲明的全局變量就具有文件作用域,它們在整個文件中都有效。例5-1 作用域?qū)嵗?include <iostream>using namespace std; /使得在當前文件中可直接引用std命名空間

14、的標識符coutint i;/全局變量,文件作用域namespace nsint j;/在ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值ns:j=6;/為全局變量j賦值/子塊1using namespace ns;/使得在當前塊中可直接引用ns命名空間的標識符int i;/局部變量,塊作用域i=7;cout<<"i="<<i<<endl;/輸出7cout<<"j="<<j<<endl;cout<<"i="<<i

15、<<endl;/輸出5參考(cout, endl是命名空間std中的全局變量):#include <iostream>/using namespace std; /使得在當前文件中可直接引用std命名空間的標識符cout,endlint i;/全局變量,文件作用域namespace nsint j;/在ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值ns:j=6;/為全局變量j賦值/子塊1using namespace ns;/使得在當前塊中可直接引用ns命名空間的標識符int i;/局部變量,塊作用域i=7;std:cout<<

16、"i="<<i<< std:endl;/輸出7std:cout<<"j="<<j<< std:endl;std:cout<<"i="<<i<< std:endl;/輸出5具有文件作用域的變量也稱為全局變量。5.1.2 可見性p150可見的標識符 程序運行到某一點,能夠引用到的標識符。文件作用域最大,接下來依次是類作用域和塊作用域。圖5-1 作用域關(guān)系圖可見性表示從內(nèi)層作用域向外層作用域“看”時能看到什么。作用域可見性的一般規(guī)則:_ 標識符聲

17、明在前,引用在后。_ 同一作用域,不能聲明同名標識符。_ 在沒有包含關(guān)系的不同作用域中聲明的同名標識符互不影響。_ 在具有包含關(guān)系的作用域中聲明了同名標識符,則外層標識符在內(nèi)層不可見。例5-l中,文件作用域與塊作用域相互包含。#include <iostream>using namespace std;int i;/全局變量,文件作用域namespace nsint j;/在ns命名空間中的全局變量void main()i=5;/文件作用域的i賦初值ns:j=6;/為全局變量j賦值/子塊1using namespace ns;int i;/局部變量,塊作用域i=7;cout<

18、<"i="<<i<<endl;/輸出7cout<<"j="<<j<<endl;cout<<"i="<<i<<endl;/輸出5在主函數(shù)內(nèi)子塊1前,可引用到具有文件作用域的變量,它是可見的。當進入子塊1,只能引用到具有局部作用域的同名變量,文件作用域的同名變量不可見,稱內(nèi)層屏蔽,或同名覆蓋,即內(nèi)層的變量覆蓋了外層的同名變量。5.2 對象的生存期p150對象(包括簡單變量)從誕生到結(jié)束的這段時間就是它的生存期。5.2.1 靜態(tài)生存期若對象

19、的生存期與程序的運行期相同,稱它具有靜態(tài)生存期。在文件作用域中聲明的對象具有靜態(tài)生存期的。若要在函數(shù)內(nèi)部的塊作用域中聲明具有靜態(tài)生存期的對象,則要使用關(guān)鍵字static。 static int i;i稱為靜態(tài)變量。其余的對象都具有動態(tài)生存期。定義時未指定初值的基本類型靜態(tài)生存期變量,初值為0;動態(tài)生存期變量,不指定初值時值不確定。5.2.2 動態(tài)生存期在塊作用域中聲明的具有動態(tài)生存期的對象,稱局部生存期對象。動態(tài)生存期對象誕生于聲明點,結(jié)束于該標識符作用域結(jié)束處。例5-2 變量的生存期與可見性。局部變量就是具有塊作用域的變量。全局變量就是具有文件作用域的變量。#include <iost

20、ream>using namespace std;int i=1;/i為全局變量,具有靜態(tài)生存期void other(void)static int a=2;static int b;/a, b為靜態(tài)局部變量,具有全局壽命,局部可見,只第一次進入函數(shù)時被初始化int c=10;/c為局部變量,具有動態(tài)生存期,每次進入函數(shù)時都初始化a=a+2; i=i+32; c=c+5;cout<<"-other-n"cout<<"i:"<<i<<" a:"<<a<<&qu

21、ot; b:"<<b<<" c:"<<c<<endl;b=a;void main()static int a;/a為靜態(tài)局部變量,具有全局壽命,局部可見int b=-10;/b, c為局部變量,具有動態(tài)生存期int c=0;cout<<"-main-n"cout<<"i:"<<i<<" a:"<<a<<" b:"<<b<<" c:&q

22、uot;<<c<<endl;c=c+8; other();cout<<"-main-n"cout<<"i:"<<i<<" a:"<<a<<" b:"<<b<<" c:"<<c<<endl;c=c+10; other();例5-3 具有靜態(tài)、動態(tài)生存期對象的時鐘程序。聲明具有函數(shù)原型作用域、塊作用域、類作用域和文件作用域的多個變量及對象,并分析各自的可見性

23、和生存期。#include <iostream>using namespace std;class clock/時鐘類定義public:clock();void settime(int newh,int newm,int news);/三個形參具有函數(shù)原型作用域void showtime();private:int hour,minute,second;/時鐘類成員函數(shù)實現(xiàn)clock:clock():hour(0),minute(0),second(0) /構(gòu)造函數(shù)void clock:settime(int newh,int newm,int news)/3個形參均具有局部作用域

24、 hour=newh; minute=newm; second=news; void clock:showtime() cout<<hour<<":"<<minute<<":"<<second<<endl;clock globclock;/聲明對象,具有靜態(tài)生存期,文件作用域void main()cout<<"第一次輸出:"<<endl;/引用文件作用域的對象globclock :globclock.showtime();/對象的

25、成員函數(shù)具有類作用域globclock.settime(8,30,30);clock myclock(globclock);/聲明具有塊作用域的對象cout<<"第二次輸出:"<<endl;myclock.showtime();/引用具有塊作用域的對象5.3 類的靜態(tài)成員p153靜態(tài)成員是解決同一個類的不同對象之間的數(shù)據(jù)和函數(shù)共享問題的。例,抽象出某公司全體雇員的共性,設計如下的雇員類:class employee/雇員類private :int empno int id string name /字符串對象.

26、若需要統(tǒng)計雇員總數(shù),這個數(shù)據(jù)存放在什么地方呢?若以類外的變量來存儲總數(shù),不能實現(xiàn)數(shù)據(jù)的隱藏。若在類中增加一個數(shù)據(jù)成員用以存放總數(shù),必然在每一個對象中都存儲一個副本,不僅冗余,且每個對象分別維護一個“總數(shù)”,勢必造成數(shù)據(jù)的不一致性。比較理想的方案是類的所有對象共同擁有一個用于存放總數(shù)的數(shù)據(jù)成員。5.3.1 靜態(tài)數(shù)據(jù)成員p154實例屬性“一個類的所有對象具有相同的屬性”,是指屬性的個數(shù)、名稱、數(shù)據(jù)類型相同,各個對象的屬性值則可各不相同。以類的非靜態(tài)數(shù)據(jù)成員表示。類屬性是描述類的所有對象的共同特征的一個數(shù)據(jù)項,對于任何對象實例,它的屬性值是相同的。通過靜態(tài)數(shù)據(jù)成員來實現(xiàn)“類屬性”。靜態(tài)數(shù)據(jù)成員的訪問

27、靜態(tài)數(shù)據(jù)成員不屬于任何一個對象,只能通過類名對它訪問,用法是“類名:標識符”。靜態(tài)數(shù)據(jù)成員的說明和定義在類的聲明中僅僅對靜態(tài)數(shù)據(jù)成員進行引用性說明,必須在文件作用域的某處用類名限定進行定義性說明,這時也可進行初始化。在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&am

28、p;)+showcount() : void#include <iostream>using namespace std;class point/point類定義public:point(int xx=0,int yy=0):x(xx),y(yy) count+; /所有對象共同維護countpoint(point &p) x=p.x; y=p.y; count+; point() count-; int getx() return x; int gety() return y; void showcount() cout<<" 對象count=&qu

29、ot;<<count<<endl; /輸出靜態(tài)數(shù)據(jù)成員private:int x,y;static int count;/靜態(tài)數(shù)據(jù)成員聲明,用于記錄點的個數(shù);int point:count=0;/靜態(tài)數(shù)據(jù)成員定義和初始化,使用類名限定void main()point a(4,5);/定義對象a,其構(gòu)造函數(shù)會使count增1cout<<"point a: "<<a.getx()<<","<<a.gety();a.showcount();/輸出對象個數(shù)point b(a); /定義對象b

30、,其拷貝構(gòu)造函數(shù)會使count增1cout<<"point b: "<<b.getx()<<","<<b.gety();b.showcount();在對類的靜態(tài)私有數(shù)據(jù)成員初始化的同時,還可引用類的其他私有成員。例,若一個類t存在類型t的靜態(tài)私有對象,則可引用該類的私有構(gòu)造函數(shù)將其初始化。5.3.2 靜態(tài)函數(shù)成員p156靜態(tài)成員函數(shù)是使用static關(guān)鍵字聲明的函數(shù)成員。靜態(tài)成員函數(shù)屬于整個類,由同一個類的所有對象共同維護,并共享。對于公有的靜態(tài)成員函數(shù),可通過類名或?qū)ο竺麃碚{(diào)用。靜態(tài)成員函數(shù)可直接訪問該類

31、的靜態(tài)數(shù)據(jù)和函數(shù)成員,而訪問非靜態(tài)數(shù)據(jù)成員,必須通過參數(shù)傳遞方式得到對象名,然后通過對象名來訪問。class apublic:static void f(a a);private:int x;void a:f(a a)cout<<x;/對x的引用是錯誤的??捎胊:f(c)調(diào)用,此時,無當前對象。cout<<a.x;/正確在uml中,靜態(tài)函數(shù)成員前添加<<static>>。例5-5 具有靜態(tài)數(shù)據(jù)和函數(shù)成員的point類。圖5-3 包含靜態(tài)函數(shù)成員的point類的uml圖point x : int y : int count : int=0+poin

32、t(xx : int=0, yy : int=0)+getx() : int+gety() : int+point(p : point&)<<static>>+showcount() : void#include <iostream>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

33、; int gety() return y; static void showcount() cout<<" 對象count="<<count<<endl; /靜態(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);cout<<"point a: "<<a.getx()<<","<<a.g

34、ety();point:showcount();/輸出對象號,類名引用point b(a);cout<<"point b: "<<b.getx()<<","<<b.gety();b.showcount();/輸出對象號,對象名引用采用靜態(tài)函數(shù)成員的好處可不依賴于任何對象,直接訪問靜態(tài)數(shù)據(jù)。5.4 類的友元p158友元提供了不同類或?qū)ο蟮某蓡T函數(shù)之間、類的成員函數(shù)與一般函數(shù)之間進行數(shù)據(jù)共享的機制。在一個類中,可用關(guān)鍵字friend將其他函數(shù)或類聲明為友元。若友元是一般函數(shù)或類的成員函數(shù),稱友元函數(shù);若友元是一

35、個類,稱友元類,友元類的所有成員函數(shù)都自動成為友元函數(shù)。5.4.1 友元函數(shù)p160友元函數(shù)是在類中用關(guān)鍵字friend修飾的非成員函數(shù)。友元函數(shù)不是本類的成員函數(shù),但是在它的函數(shù)體中可通過對象名訪問類的私有和保護成員。在uml中,友元函數(shù)前添加<<friend>>。例5-6 使用友元函數(shù)計算兩點間的距離。圖5-4 包含友元函數(shù)成員的point類的uml圖point x : int y : int+point(xx : int=0, yy : int=0)+getx() : int+gety() : int<<friend>>+dist(a :

36、point&, b : point&) : foat#include <iostream>#include <cmath>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 &p2);/友元函數(shù)聲明private:int x,y;float dist(point &p1

37、,point &p2)/友元函數(shù)實現(xiàn)double x=double(p1.x-p2.x);/通過對象訪問私有數(shù)據(jù)成員double y=double(p1.y-p2.y);return static_cast<float>(sqrt(x*x+y*y);void main()point myp1(1,1),myp2(4,5);cout<<"距離是:"cout<<dist(myp1,myp2)<<endl;5.4.2 友元類p161若a類為b類的友元類,則a類的所有成員函數(shù)都是b類的友元函數(shù),都可以訪問b類的私有和保護成員。

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

39、ublic:void display() cout<<x<<endl; int getx() return x; friend class b;private:int x;class bpublic:void set(int i);void display() cout<<a.x<<endl; private:a a;void b:set(int i)a.x=i;/由于b是a的友元,所以在b的成員函數(shù)中可以訪問a類對象的私有成員void main()b b;b.set(5);b.display();注意:第一,友元關(guān)系是不能傳遞的。第二,友元關(guān)系

40、是單向。第三,友元關(guān)系是不被繼承的。5.5 共享數(shù)據(jù)的保護p1635.5.1 常對象聲明格式:const 類型說明符 對象名;或類型說明符 const 對象名;常對象必須進行初始化,且不能被更新。語法如何保障常對象的值不被改變呢?改變對象的數(shù)據(jù)成員值有兩個途徑:一是在類外通過對象名訪問其公有數(shù)據(jù)成員,這時語法會限制不能再賦值。二是在類的成員函數(shù)中改變數(shù)據(jù)成員的值,規(guī)定不能通過常對象調(diào)用普通的成員函數(shù)。5.5.2 用const修飾的類成員p1641. 常成員函數(shù)聲明格式:類型說明符 函數(shù)(參數(shù)表)const;注意: const是函數(shù)類型的一個組成部分。 常成員函數(shù)不能更新對象的數(shù)據(jù)成員,也不能調(diào)

41、用該類中沒有用const修飾的成員函數(shù)。 常對象只能調(diào)用它的常成員函數(shù)。 const可用于對重載函數(shù)的區(qū)分。例如, void print(); void print() const;這是對print的有效重載。在uml中,常成員函數(shù)前添加<<const>>。例5-7 常成員函數(shù)舉例。圖5-6 包含常成員函數(shù)的r類的uml圖r r1 : int r2 : int+r(rr1 : int, rr2 : int)+print() : void<<const>>+print() : void#include <iostream>using n

42、amespace 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() cout<<r1<<":"<<r2<<endl; void r:print() const cout<<r1<<""<<r2<<endl; void main()r a(5,4);a.print();

43、const r b(20,52);b.print();2. 常數(shù)據(jù)成員類的成員數(shù)據(jù)也可以是常量。使用const說明的數(shù)據(jù)成員為常數(shù)據(jù)成員。任何函數(shù)中都不能對常數(shù)據(jù)成員賦值。構(gòu)造函數(shù)對常數(shù)據(jù)成員進行初始化,就只能通過初始化列表。在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 <iostream>using namespace std;class apublic:a(int i);void pri

44、nt();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ù)成員只能通過初始化列表來獲得初值 void a:print() cout<<a<<":"<<b<<endl; void main()/*建立對象a1和a2,并以100和0作為初值,分別調(diào)用構(gòu)造函數(shù),通過構(gòu)造函數(shù)的初始化列表給對象的常數(shù)據(jù)成員賦初值*/a a1(100),a2(0);a1.print();a

45、2.print();5.5.3 常引用p166常引用的說明形式:const 類型說明符 &引用名;常引用所引用的對象不能被更新。若用常引用做形參,便不會發(fā)生對實參意外的更改。例5-9 常引用做形參#include <iostream>#include <cmath>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 po

46、int &p1,const point &p2);/友元函數(shù)聲明private:int x,y;float dist(const point &p1, const point &p2)/友元函數(shù)實現(xiàn)double x=double(p1.x-p2.x);/通過對象訪問私有數(shù)據(jù)成員double y=double(p1.y-p2.y);return static_cast<float>(sqrt(x*x+y*y);void main()const point myp1(1,1),myp2(4,5);cout<<"距離是:"c

47、out<<dist(myp1,myp2)<<endl;*5.6 多文件結(jié)構(gòu)和編譯預處理命令p1685.6.1 c+程序的一般組織結(jié)構(gòu)通常一個項目至少劃分為三個文件:類聲明文件(*.h文件)類實現(xiàn)文件(*.cpp文件)類的使用文件(*.cpp,主函數(shù)文件)每個源程序文件稱為一個編譯單元。c+語法要求一個類的聲明必須出現(xiàn)在所有使用該類的編譯單元中。慣用的做法將類的聲明寫在頭文件中,使用該類的編譯單元則包含這個頭文件。例5-10 具有靜態(tài)數(shù)據(jù)、函數(shù)成員的point類,多文件組織。/文件1,類的聲明,point.h#include <iostream>using n

48、amespace std;class pointpublic:point(int xx=0,int yy=0)x=xx; y=yy; countp+; ;point(point &p);point()countp-;int getx()return x;int gety()return y;static void getc() cout<<"對象id="<<countp<<endl; /靜態(tài)函數(shù)成員private:int x,y;static int countp;/靜態(tài)數(shù)據(jù)成員聲明;/文件2,類的實現(xiàn),point.cpp#inc

49、lude “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,5);cout<<"point a,"<<a.getx()<<","<<a.gety();a.getc();/輸出對象號,對象名引用point b(a);cout<<"po

50、int b,"<<b.getx()<<","<<b.gety();point:getc();/輸出對象號,類名引用圖5-8 c+多文件組織結(jié)構(gòu)圖#include指令的作用將指定的源文件嵌入到當前源文件中#include指令所在位置,被嵌入的文件可以是.h文件,也可以是.cpp文件。#include兩上書寫方式#include<文件名>,按照標準方式搜索要嵌入的文件,該文件位于c+系統(tǒng)目錄的include子目錄下,一般包含系統(tǒng)提供的標準文件時采用這樣的方式。#include"文件名",首先在當前目錄

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

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

53、文件作用域中定義變量時以static修飾,則該變量的作用范圍僅限于定義它的編譯單元。2. 外部函數(shù)非成員函數(shù)具有文件作用域,可以在不同的編譯單元被調(diào)用,只要在調(diào)用之前聲明函數(shù)原型即可??梢栽诼暶骱瘮?shù)原型或定義函數(shù)時用extern修飾,其效果與不加修飾的默認狀態(tài)是一樣的。若在聲明一個函數(shù)原型時或定義函數(shù)時冠以static修飾,就將函數(shù)的作用域限制在當前的編譯單元內(nèi)。5.6.3 標準c+庫p172標準c+類與組件在邏輯上分為6種類型:輸入/輸出類容器類與adt(抽象數(shù)據(jù)類型)存儲管理類算法錯誤處理運行環(huán)境支持對庫中預定義內(nèi)容的說明分別存在于不同的頭文件中,要使用這些預定義的成分,就要將相應的頭文件

54、包含到源程序中。標準c+庫不再有“.h”擴展名,但仍保留18個帶有“.h”擴展名的c頭文件。兩種形式的頭文件不能混用。比如,若已經(jīng)包含頭文件iostream,就不能再包含math.h,而要代之以新的頭文件cmath。使用標準c+庫時,在緊接著所有的include指令之后,加入using namespace std;將指定命名空間中的名稱引入到當前命名空間中。否則,需要在使用std命名空間中的標識符時冠以命名空間名“:”。(第10章)5.6.4 編譯預處理p173編譯器在對源程序進行編譯之前,首先要由預處理程序?qū)Τ绦蛭谋具M行預處理。預處理程序提供了一組編譯預處理指令和預處理操作符。所有的預處理指

55、令在程序中都是以“#”來引導,每一條預處理指令單獨占用行,不要用分號結(jié)束。預處理指令可以根據(jù)需要出現(xiàn)在程序中的任何位置。1. #include指令(文件包含指令)其作用是將另一個源文件嵌入到當前源文件中該點處。 include<文件名>按標準方式搜索,文件位于c+系統(tǒng)目錄的include子目錄下。 include"文件名"首先在當前目錄中搜索,若沒有,再按標準方式控索。2. #define和#undef指令#define用來定義符號常量,例如,#define pi 3.14。#undef用來刪除由#define定義的宏,使之不再起作用。3. 條件編譯指令用來限定

56、程序中的某些內(nèi)容要在滿足一定條件的情況下才參與編譯。常用的條件編譯語句有下列5種形式: 形式1#if 常量表達式程序段 /當“常量表達式”非0時編譯本程序段#endif 形式2#if 常量表達式程序段1 /當“常量表達式”非0時編譯本程序段#else程序段2 /當“常量表達式”為0時編譯本程序段#endif 形式3#if 常量表達式1程序段1 /當“常量表達式1”非0時編譯本程序段#elif常量表達式2程序段2 /否則,當“常量表達式2”非0時編譯本程序段 .#elif常量表達式n程序段n /否則,當“常量表達式n”非0時編譯本程序段#else程序段n+1 /其他情況下編譯本程序段#endif

57、 形式4#ifdef 標識符程序段1 /若“標識符”經(jīng)#define定義過,且未經(jīng)#undef刪除,則編譯本程序段#else程序段2 /否則編譯本程序段#endif#ifdef 標識符程序段 /若“標識符”經(jīng)#define定義過,且未經(jīng)#undef刪除,則編譯本程序段#endif 形式5#ifndef 標識符程序段1 /若“標識符”未定義過,則編譯本程序段#else程序段2 /否則編譯本程序段#endif#ifdef 標識符程序段 /若“標識符”未定義過,則編譯本程序段#endif4. defined操作符defined是一個預處理操作符,而不是指令,因此不要以#開頭。defined(標識符)若“標識符”在此前經(jīng)#define定義過,且未經(jīng)#undef刪除,則上述表達式為非0,否則為0。下面兩種寫法是完全等效的:#ifndef myhead_h#define myhead_h.#end

溫馨提示

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

評論

0/150

提交評論