




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第6章 類的數據共享與保護本章主要內容本章主要內容對象對象(變量變量)的作用域、可見性與生存期的作用域、可見性與生存期類的靜態成員類的靜態成員類的友元類的友元常引用、常對象和常成員常引用、常對象和常成員6.1 對象(變量)的作用域、可見性和生存期 對象對象(變量變量)的作用域:指對象的有效范圍。的作用域:指對象的有效范圍。 - 一般情況下一般情況下,對象在其作用域內是可見的和存對象在其作用域內是可見的和存在的,對象的作用域、可見性和生存期三者是一在的,對象的作用域、可見性和生存期三者是一致的。致的。 對象對象(變量變量)的可見性:指不同作用域的同名對象的可見性:指不同作用域的同名對象在其作用域
2、范圍內的某一處是否可被引用。在其作用域范圍內的某一處是否可被引用。 對象對象(變量變量)的生存期:指對象從誕生的生存期:指對象從誕生(占據內存占據內存)到結束到結束(不占內存不占內存)的這段時間。在生存期內的這段時間。在生存期內, 對象對象或變量將保持它的值不變或變量將保持它的值不變, 直到它們被更新為止。直到它們被更新為止。 -對象對象(變量變量)的生存期分為動態生存期和靜態生的生存期分為動態生存期和靜態生存期兩種。存期兩種。6.1.1 對象對象(變量變量)的作用域的作用域局部對象局部對象(變量變量):(函數內函數內)塊作用域塊作用域 - 從聲明處開始到塊結束的花括號為止從聲明處開始到塊結束
3、的花括號為止形參對象形參對象(變量變量):函數作用域:函數作用域 - 在整個函數內有效在整個函數內有效 成員對象成員對象(變量變量):類作用域:類作用域 - 在整個類內有效,即在所有成員函數內有效在整個類內有效,即在所有成員函數內有效全局對象全局對象(變量變量):文件作用域:文件作用域 - 在整個文件內有效在整個文件內有效6.1.2 對象對象(變量變量)的可見性的可見性 一般情況下對象一般情況下對象(變量變量)在其作用域范圍內的任一處是在其作用域范圍內的任一處是可見的,即可被引用。可見的,即可被引用。 在有不同作用域的多個同名對象在有不同作用域的多個同名對象(變量變量)的情況下,外的情況下,外
4、層對象層對象(變量變量)在內層不可見在內層不可見, 被隱藏起來。被隱藏起來。塊作用域塊作用域類作用域類作用域文件作用域文件作用域函數作用域函數作用域作用域關系圖作用域關系圖 不同作用域的同名對象的不同作用域的同名對象的 包含關系如右圖所示。包含關系如右圖所示。 被隱藏的成員對象被隱藏的成員對象(變量變量) 可加可加“類名類名:”來顯式地引來顯式地引用用, 被隱藏的全局對象被隱藏的全局對象(變量變量) 可加可加“:”來顯式地引用。來顯式地引用。6.1.3 對象對象(變量變量)的生存期的生存期 對象對象(變量變量)的生存期:動態生存期、靜態生存期。的生存期:動態生存期、靜態生存期。 動態生存期:對
5、象動態生存期:對象(變量變量)在程序運行期間隨時誕生在程序運行期間隨時誕生和消失,如局部變量、形參變量、成員變量。和消失,如局部變量、形參變量、成員變量。 靜態生存期:對象靜態生存期:對象(變量變量)在程序運行期間一直存在,在程序運行期間一直存在,如全局變量。如全局變量。 C語言中靜態局部變量:作用域與生存期不一致。語言中靜態局部變量:作用域與生存期不一致。 C+在類的成員函數中定義一個靜態局部變量:該在類的成員函數中定義一個靜態局部變量:該類的所有對象在調用這個成員函數時將共享這個類的所有對象在調用這個成員函數時將共享這個變量。變量。 C+類的成員為靜態成員:靜態成員為該類所有對類的成員為靜
6、態成員:靜態成員為該類所有對象所共享,它不屬于某個對象的,見下節。象所共享,它不屬于某個對象的,見下節。 程序實例程序實例6.2 靜態成員(static) 在在C語言中,當把函數的一個局部變量說明為語言中,當把函數的一個局部變量說明為靜態的,則該變量在函數調用結束后其值仍然存在,靜態的,則該變量在函數調用結束后其值仍然存在,但其它函數不能引用。若下次再調用該函數,則該但其它函數不能引用。若下次再調用該函數,則該變量的值不再重新初始化為變量的值不再重新初始化為0,函數可以使用上次,函數可以使用上次調用所保留的值。調用所保留的值。 在在C+中,對于某個類所定義的每一個對象,中,對于某個類所定義的每
7、一個對象,都有其屬于自身的數據成員與成員函數,不同對象都有其屬于自身的數據成員與成員函數,不同對象之間的成員是互不相干的,這類似于之間的成員是互不相干的,這類似于C中函數內的中函數內的局部變量,不同時間函數調用的局部變量是互不相局部變量,不同時間函數調用的局部變量是互不相干的。但它們都同名。干的。但它們都同名。 因此,在因此,在C+中,當把類的某個成員用關鍵中,當把類的某個成員用關鍵字字static說明為靜態成員時說明為靜態成員時, 就是把該成員定義為就是把該成員定義為在該類范圍內的全局成員,即無論這個類建立了在該類范圍內的全局成員,即無論這個類建立了多少個對象,所有對象都共用這個成員。因此多
8、少個對象,所有對象都共用這個成員。因此,靜態成員的主要用途是定義類的各個對象所共用靜態成員的主要用途是定義類的各個對象所共用的數據成員或成員函數,其中尤其是數據成員。的數據成員或成員函數,其中尤其是數據成員。 下面對靜態數據成員和靜態成員函數分別進下面對靜態數據成員和靜態成員函數分別進行討論。行討論。 6.2.1 靜態數據成員靜態數據成員 在一個類中,若將一個數據成員說明為在一個類中,若將一個數據成員說明為static,則該數據成員稱為靜態數據成員,無論建立多少個則該數據成員稱為靜態數據成員,無論建立多少個該類的對象,都只有一個共同的數據成員。該類的對象,都只有一個共同的數據成員。static
9、數據成員在編譯時按全局變量方式被分配存儲單元數據成員在編譯時按全局變量方式被分配存儲單元并初始化,默認的初始值為零。并初始化,默認的初始值為零。 欲聲明一個成員為靜態的,只要在其前方加上欲聲明一個成員為靜態的,只要在其前方加上關鍵字關鍵字static即可即可, 如在如在Point類定義一個靜態數據成類定義一個靜態數據成員員countP : static int countP; 靜態數據成員的使用與普通數據成員的使用靜態數據成員的使用與普通數據成員的使用并無差異,但必須注意兩點:并無差異,但必須注意兩點: a.由于靜態數據成員在該類范圍內是一個全局由于靜態數據成員在該類范圍內是一個全局變量,因此
10、必須在類定義外的全局范圍中給它賦變量,因此必須在類定義外的全局范圍中給它賦初值,然后才能使用。如下所示:初值,然后才能使用。如下所示: int Point:countP=0; 給靜態數據成員賦初值時必須同時指名數據類給靜態數據成員賦初值時必須同時指名數據類型與所屬的類,用類名加作用域運算符來限定。這型與所屬的類,用類名加作用域運算符來限定。這里的數據類型必須與在類中聲明的數據類型一致。里的數據類型必須與在類中聲明的數據類型一致。 由于靜態數據成員并不特別屬于某一個對象,由于靜態數據成員并不特別屬于某一個對象,上述這樣的賦初值語句只能在整個程序中出現一次。上述這樣的賦初值語句只能在整個程序中出現
11、一次。因此,程序員最好不要把靜態成員的初始化定義在因此,程序員最好不要把靜態成員的初始化定義在頭文件中,因為頭文件可能在程序中多次被引入使頭文件中,因為頭文件可能在程序中多次被引入使用,否則將發生錯誤。用,否則將發生錯誤。 b.當靜態數據成員聲明于類的當靜態數據成員聲明于類的public區時,由于區時,由于它并不特別屬于某一個對象它并不特別屬于某一個對象, 在類范圍內是全局的在類范圍內是全局的,因此可以在程序的任何地方直接引用該靜態數據成因此可以在程序的任何地方直接引用該靜態數據成員,但使用時必須加上類范圍的限制,如:員,但使用時必須加上類范圍的限制,如: cout對象個數為:對象個數為:Po
12、int:countP; 下面我們來看看例下面我們來看看例5-4 (P138)。 由于靜態數據成員是所有同類對象所共用的數由于靜態數據成員是所有同類對象所共用的數據,所以據,所以 A.getC(); B.getC();這兩個輸出語句的結果是相同的,即:這兩個輸出語句的結果是相同的,即: 對象個數為:對象個數為:2 對象個數為:對象個數為:2 從程序的最后兩句可以看出,類的從程序的最后兩句可以看出,類的public數據數據成員有兩種使用方法:成員有兩種使用方法:6.2.2 靜態成員函數靜態成員函數 成員函數也可以被聲明為靜態的。當一個成成員函數也可以被聲明為靜態的。當一個成員函數被聲明為員函數被聲
13、明為static時,表明該靜態成員函數只時,表明該靜態成員函數只屬于一個類,而不屬于該類的任何對象。因此,屬于一個類,而不屬于該類的任何對象。因此,在訪問靜態成員函數時,最好用類名加作用域運在訪問靜態成員函數時,最好用類名加作用域運算符來調用該靜態成員函數。算符來調用該靜態成員函數。 對象名對象名.數據成員數據成員或或 類名類名:數據成員數據成員 第一種方式主要用于非靜態數據成員,第二第一種方式主要用于非靜態數據成員,第二種主要用于靜態數據成員。種主要用于靜態數據成員。 實際上,當某成員函數只使用靜態數據成員時,實際上,當某成員函數只使用靜態數據成員時,應該把該成員函數定義為靜態成員函數。這是
14、因為,應該把該成員函數定義為靜態成員函數。這是因為,一個僅使用到靜態數據成員的成員函數通過某類的一個僅使用到靜態數據成員的成員函數通過某類的對象來調用是沒有任何意義的,且容易造成閱讀上對象來調用是沒有任何意義的,且容易造成閱讀上的混淆,閱讀者無法從程序中直接看出該成員函數的混淆,閱讀者無法從程序中直接看出該成員函數引用了靜態數據成員。引用了靜態數據成員。 因此因此A.getC( ); B.getC( );改為:改為: Point:getC( ); Point:getC( );更為妥當。更為妥當。見例見例5-5 (P140)。 另一方面另一方面, 靜態成員函數不屬于某個對象的靜態成員函數不屬于某
15、個對象的, 因因此此, 在靜態成員函數訪問非靜態成員時,必須要指明在靜態成員函數訪問非靜態成員時,必須要指明所要訪問的對象。例如,若在所要訪問的對象。例如,若在getC中要訪問非靜態中要訪問非靜態成員成員X, 則則getC必須修改為:必須修改為:見修改后的例見修改后的例5-5析構函數有代碼析構函數有代碼 static void getC(Point &p) cout對象個數為:對象個數為:countPendl; cout“X:”Xendl; /錯誤錯誤 cout“X:p.Xendl; 則則main函數中的調用語句改為:函數中的調用語句改為: Point:getC(A); Point:g
16、etC(B);6.3 友元(friend) 前面已講過前面已講過, 一個對象的私有數據只能通過成員一個對象的私有數據只能通過成員函數進行訪問。這種數據封裝的方法雖有許多優點函數進行訪問。這種數據封裝的方法雖有許多優點,但在某些情況下也帶來許多不便但在某些情況下也帶來許多不便, 如某個函數需要使如某個函數需要使用多個類的多個相關數據用多個類的多個相關數據, 或類或類Y的所有成員函數要的所有成員函數要訪問類訪問類X的私有數據。出于效率而非技術的考慮的私有數據。出于效率而非技術的考慮, C+提供了友元提供了友元(friend)這樣一種輔助手段這樣一種輔助手段, 允許外面允許外面的類或函數去訪問一個類
17、的私有數據。的類或函數去訪問一個類的私有數據。 友元分為兩種情況:將一個普通函數聲明為某友元分為兩種情況:將一個普通函數聲明為某類的友元和將一個類聲明為另一個類的友元。類的友元和將一個類聲明為另一個類的友元。 6.3.1 友元函數友元函數 要聲明一個普通函數為某類的友元要聲明一個普通函數為某類的友元, 只要在該類只要在該類定義中任何一處定義中任何一處(不管是不管是private、protected或是或是public區區)提供對該函數的聲明,并在其最前方加上提供對該函數的聲明,并在其最前方加上關鍵字關鍵字friend即可。下面是計算兩點距離的實例:即可。下面是計算兩點距離的實例: class
18、Point int X,Y; friend float fdist(Point &p1, Point &p2);/友元函數友元函數public: Point (int xx=0, int yy=0)X=xx; Y=yy; 與成員函數一樣,友元函數可以在類與成員函數一樣,友元函數可以在類Point的的內部定義,也可以在類內部定義,也可以在類Point的外部定義。當在類的外部定義。當在類外定義時外定義時, 友元函數不需要加友元函數不需要加“類類:”。如上述。如上述fDist函數在類函數在類Point外定義:外定義: double fDist (Point &p1, Poin
19、t &p2) double x=double(p1.X-p2.X); double y=double(p1.Y-p2.Y); return sqrt (x*x+y*y); 見例見例5-6 (P143) 請注意友元函數與成員函數在定義和使用上的請注意友元函數與成員函數在定義和使用上的區別。成員函數與友元函數的主要區別是成員函數區別。成員函數與友元函數的主要區別是成員函數是屬于某個類的,而友元函數不屬于某個類。是屬于某個類的,而友元函數不屬于某個類。 在友元函數中,必須指定所要訪問的對象,這在友元函數中,必須指定所要訪問的對象,這在三個地方體現出來:在三個地方體現出來: 在參數中有在參數中
20、有2個個Point類的引用類的引用; 在實現代碼中通過引用對象在實現代碼中通過引用對象p1和和“.”來使用數據成員;來使用數據成員; 使用友元函數使用友元函數(即調用該友元函數即調用該友元函數)時必須有該類對象作為實時必須有該類對象作為實參。參。 6.2.2 友元類友元類 我們可以將類我們可以將類A聲明為類聲明為類B的友元,這樣類的友元,這樣類A的的所有成員函數就可以訪問類所有成員函數就可以訪問類B的私有數據。例如:的私有數據。例如: class A; /一個類聲明語句一個類聲明語句 class B friend A; /聲明聲明A為為B的友元類的友元類 int i; void m_func(
21、 ); ;class A public: void f_f1(B &); void f_f2(B &); .; 對于友元類的成員函數的使用和定義方式,對于友元類的成員函數的使用和定義方式,由于它兼具有類和友元函數的雙重特點,所以它由于它兼具有類和友元函數的雙重特點,所以它的使用和定義方式頗具特色,具體如下:的使用和定義方式頗具特色,具體如下: a.由于它是屬于某個類由于它是屬于某個類(A),所以在類外定義,所以在類外定義時必須加作用域運算符來限定它屬于某一類時必須加作用域運算符來限定它屬于某一類(A)的,的,在使用時必須加對象名和成員運算符來指定哪一在使用時必須加對象名和成員運
22、算符來指定哪一個對象調用它;個對象調用它; b.由于它是另一個類由于它是另一個類(B)的友元,所以在其參的友元,所以在其參數中必須用該類數中必須用該類(B)的對象和引用作為形參。的對象和引用作為形參。 c.在實現代碼上,必須用該類在實現代碼上,必須用該類(B)的對象名加成的對象名加成員運算符來使用該類員運算符來使用該類(B)的私有數據。的私有數據。 見例見例(P145)。 友元說明只有在確實必要時才應使用,即在友元說明只有在確實必要時才應使用,即在沒有它時必須建立一個復雜的類等級的時候才使用。沒有它時必須建立一個復雜的類等級的時候才使用。從性質上來說,友元是一種數據共享,它破壞了類從性質上來說
23、,友元是一種數據共享,它破壞了類的封裝性,因此要盡量少用。的封裝性,因此要盡量少用。 在使用友元時還要注意:在使用友元時還要注意:(1)友元不具有可傳友元不具有可傳遞性,如遞性,如B是是A的一個友元,的一個友元,A是是C的一個友元,并的一個友元,并不能得出不能得出B是是C的友元的結論。的友元的結論。(2)友元關系是單向友元關系是單向的的, 如果如果B類是類是A類的友元,類的友元,B類的成員函數可以訪類的成員函數可以訪問問A類的私有數據,但類的私有數據,但A類的成員函數不能訪問類的成員函數不能訪問B類的私有數據。類的私有數據。(3)友元關系不能被繼承,如果友元關系不能被繼承,如果B類類是是A類的
24、友元,類的友元,B類的派生類不能自動成為類的派生類不能自動成為A類的類的友元。友元。6.4 常對象和常成員(const) 雖然數據隱藏保證了數據的安全性,但各種雖然數據隱藏保證了數據的安全性,但各種形式的數據共享卻又不同程度地破壞了數據的安全。形式的數據共享卻又不同程度地破壞了數據的安全。因此,對于既需要共享、又需要防止改變的數據應因此,對于既需要共享、又需要防止改變的數據應該聲明為常量。因為常量在程序運行期間是不可改該聲明為常量。因為常量在程序運行期間是不可改變的,所以可以有效地保護數據。變的,所以可以有效地保護數據。 本節介紹用本節介紹用const定義的常對象、常成員和常引定義的常對象、常
25、成員和常引用。用。6.4.1 常對象常對象 常對象是指常類型對象,即對象常量,定義的常對象是指常類型對象,即對象常量,定義的語法形式為:語法形式為: 類名類名 const 對象名對象名(初值初值);或或 const 類名類名 對象名對象名(初值初值);定義常對象同樣要賦初值定義常對象同樣要賦初值, 并且該對象不得再更新。并且該對象不得再更新。另外,常對象只能調用它的常成員函數,而不能調另外,常對象只能調用它的常成員函數,而不能調用其他成員函數。參見下面的常成員函數。用其他成員函數。參見下面的常成員函數。6.4.3 常成員常成員 使用使用constconst關鍵字說明的函數為常成員函數,關鍵字說明的函數為常成員函數,常成員函數據說明格式如下:常成員函數據說明格式如下: 類型說明符類型說明符 函數名函數名( (參數表參數表)const;)const;1. 常成員函數常成員函數留意:留意: (1) const(1) const是函數類型的一個組成部分,因此在是函數類型的一個組成部分,因此在實現部分也要帶實現部分也要帶constconst關鍵字關鍵字, , 并且可用于對重載并且可用于對重載函數的區分。函數的區分。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030中國合成草行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國可變排量活塞泵行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國雙軸取向聚丙烯薄膜和片材行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國醫學影像信息系統行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國動態心電圖監護儀行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國農貿電商平臺行業市場深度調研及競爭格局與投資策略研究報告
- 2025-2030中國公路和鐵路智能運輸系統行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國免疫血液學行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國人造土行業市場發展趨勢與前景展望戰略研究報告
- 2025-2030中國交通檢測設備行業發展分析及發展趨勢與投資前景預測研究報告
- 2024年鄭州鐵路職業技術學院單招職業傾向性測試題庫必考題
- 2025年山東省濟南市平陰縣中考一模英語試題(原卷版+解析版)
- 移動業務代辦協議書
- 2025年CSCO胃癌診療指南解讀
- 2025屆廣東省高三一模生物學試卷(原卷版+解析版)
- 述職報告:崗位認知
- 部編版語文三年級下冊第六單元集體備課
- 2025年中職入團考試題型及答案
- 2025年離婚協議書兩個小孩模板
- 2025年貴陽租賃合同范文(含房屋租賃保證金條款)
- 基本護理技術搶救工作的組織管理講解
評論
0/150
提交評論