




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第第8章章 類和對象類和對象第第9章章 關于類和對象的進一步討論關于類和對象的進一步討論第第10章章 運算符重載運算符重載第第3 3篇篇基于對象的程序設計基于對象的程序設計第第8章章 類和對象類和對象8.1 面向對象程序設計方法概述面向對象程序設計方法概述8.2 類的聲明和對象的定義類的聲明和對象的定義8.3 類的成員函數類的成員函數8.4 對象成員的引用對象成員的引用8.5 類的封裝性和信息隱蔽類的封裝性和信息隱蔽8.6 類和對象的簡單應用舉例類和對象的簡單應用舉例面向對象的程序設計的思路和人們日常生活中處理面向對象的程序設計的思路和人們日常生活中處理問題的思路是相似的。在自然世界和社會生活
2、中,問題的思路是相似的。在自然世界和社會生活中,一個復雜的事物總是由許多部分組成的。一個復雜的事物總是由許多部分組成的。當人們生產汽車時,分別設計和制造發動機、底盤、當人們生產汽車時,分別設計和制造發動機、底盤、車身和輪子,最后把它們組裝在一起。在組裝時,車身和輪子,最后把它們組裝在一起。在組裝時,各部分之間有一定的聯系,以便協調工作。各部分之間有一定的聯系,以便協調工作。這就是面向對象的程序設計的基本思路。這就是面向對象的程序設計的基本思路。為了進一步說明問題,下面先討論幾個有關的概念。為了進一步說明問題,下面先討論幾個有關的概念。8.1 面向對象程序設計方法概述面向對象程序設計方法概述8.
3、1.1 什么是面向對象的程序設計什么是面向對象的程序設計1. 對象對象客觀世界中任何一個事物都可以看成一個對象客觀世界中任何一個事物都可以看成一個對象(object)。對象可大可小。對象可大可小。對象是構成系統的基本單位對象是構成系統的基本單位。任何一個對象都應當具有這兩個要素,即任何一個對象都應當具有這兩個要素,即屬性屬性(attribute)和和行為行為(behavior),它能根據外界給的信它能根據外界給的信息進行相應的操作。息進行相應的操作。一個對象往往是由一組屬性和一個對象往往是由一組屬性和一組行為構成的。一般來說,凡是具備屬性和行為一組行為構成的。一般來說,凡是具備屬性和行為這兩種
4、要素的,都可以作為對象。這兩種要素的,都可以作為對象。在一個系統中的多個對象之間通過一定的渠道相互在一個系統中的多個對象之間通過一定的渠道相互聯系,如圖聯系,如圖8.1示意。示意。要使某一個對象實現某一種要使某一個對象實現某一種行為行為(即操作即操作),應當向它傳送相應的消息。對象之,應當向它傳送相應的消息。對象之間就是這樣通過間就是這樣通過發送和接收消息發送和接收消息互相聯系的。互相聯系的。圖圖8.1 圖圖8.2 使用面向對象的程序設計方法設計一個復雜的軟使用面向對象的程序設計方法設計一個復雜的軟件系統時,首要的問題是確定該系統是由哪些對象件系統時,首要的問題是確定該系統是由哪些對象組成的,
5、并且設計這些對象。組成的,并且設計這些對象。在在c+中,每個對象中,每個對象都是由數據和函數都是由數據和函數(即操作代碼即操作代碼)這兩部分組成的這兩部分組成的,見見圖圖8.2。數據體現了前面提到的。數據體現了前面提到的“屬性屬性”,如一個如一個三角形對象,它的三角形對象,它的3個邊長就是它的屬性。個邊長就是它的屬性。函數是函數是用來對數據進行操作的,以便實現某些功能,用來對數據進行操作的,以便實現某些功能,例如例如可以通過邊長計算出三角形的面積,并且輸出三角可以通過邊長計算出三角形的面積,并且輸出三角形的邊長和面積。計算三角形面積和輸出有關數據形的邊長和面積。計算三角形面積和輸出有關數據就是
6、前面提到的行為,在程序設計方法中也稱為就是前面提到的行為,在程序設計方法中也稱為方方法法(method)。調用對象中的函數就是向該對象傳送調用對象中的函數就是向該對象傳送一個消息一個消息(message),要求該對象實現某一行為,要求該對象實現某一行為(功功能能)。2. 封裝與信息隱蔽封裝與信息隱蔽對一個對象進行封裝處理,把它的一部分屬性和功對一個對象進行封裝處理,把它的一部分屬性和功能對外界屏蔽,也就是說從外界是看不到的能對外界屏蔽,也就是說從外界是看不到的,甚至甚至是不可知的。是不可知的。面向對象程序設計的一個重要特點就是面向對象程序設計的一個重要特點就是“封裝性封裝性” 所謂所謂“封裝封
7、裝”,指兩方面的含義:,指兩方面的含義: 一是將有關的數據和操作代碼封裝在一個對象中,形成一一是將有關的數據和操作代碼封裝在一個對象中,形成一個基本單位,各個對象之間相對獨立,互不干擾。個基本單位,各個對象之間相對獨立,互不干擾。二是將對象中某些部分對外隱蔽,即隱蔽其內部細節,只二是將對象中某些部分對外隱蔽,即隱蔽其內部細節,只留下少量接口,以便與外界聯系,接收外界的消息。留下少量接口,以便與外界聯系,接收外界的消息。這種這種對外界隱蔽的做法稱為對外界隱蔽的做法稱為信息隱蔽信息隱蔽。信息隱蔽還有利于數據。信息隱蔽還有利于數據安全,防止無關的人了解和修改數據。安全,防止無關的人了解和修改數據。c
8、+的對象中的函數名就是對象的的對象中的函數名就是對象的對外接口對外接口,外界外界可以通過函數名來調用這些函數來實現某些行為可以通過函數名來調用這些函數來實現某些行為(功能功能)。這些將在以后詳細介紹。這些將在以后詳細介紹。3. 抽象抽象在程序設計方法中,常用到在程序設計方法中,常用到抽象抽象(abstraction)這一)這一名詞。名詞。抽象的過程是將有關事物的共性歸納、集中抽象的過程是將有關事物的共性歸納、集中的過程。的過程。抽象的作用是表示同一類事物的本質抽象的作用是表示同一類事物的本質。c和和c+中中的數據類型就是對一批具體的數的抽象。的數據類型就是對一批具體的數的抽象。對象是具體存在的
9、,如一個三角形可以作為一個對對象是具體存在的,如一個三角形可以作為一個對象,象,10個不同尺寸的三角形是個不同尺寸的三角形是10個對象。如果這個對象。如果這10個三角形對象有相同的屬性和行為,可以將它們抽個三角形對象有相同的屬性和行為,可以將它們抽象為一種類型,稱為三角形類型。在象為一種類型,稱為三角形類型。在c+中,這種中,這種類型就稱為類型就稱為“類類(class)”。這這10個三角形就是屬于個三角形就是屬于同一同一“類類”的對象。的對象。類是對象的抽象,而對象則是類是對象的抽象,而對象則是類的特例,或者說是類的具體表現形式。類的特例,或者說是類的具體表現形式。4. 繼承與重用繼承與重用如
10、果在軟件開發中已經建立了一個名為如果在軟件開發中已經建立了一個名為a的的“類類”,又想另外建立一個名為又想另外建立一個名為b的的“類類”,而后者與前者,而后者與前者內容基本相同,只是在前者的基礎上增加一些屬性內容基本相同,只是在前者的基礎上增加一些屬性和行為,只需在類和行為,只需在類a的基礎上增加一些新內容即可。的基礎上增加一些新內容即可。這就是面向對象程序設計中的這就是面向對象程序設計中的繼承機制繼承機制。利用繼承利用繼承可以簡化程序設計的步驟。可以簡化程序設計的步驟。“卡車卡車”繼承了繼承了“汽車汽車”的基本特征,又增加了新的基本特征,又增加了新的特征,的特征,“汽車汽車”是父類,或稱為基
11、類,是父類,或稱為基類,“卡車卡車”是從是從“汽車汽車”派生出來的,稱為子類或派生類。派生出來的,稱為子類或派生類。c+提供了繼承機制,采用繼承的方法可以很方便提供了繼承機制,采用繼承的方法可以很方便地利用一個已有的類建立一個新的類。這就是常說地利用一個已有的類建立一個新的類。這就是常說的的“軟件重用軟件重用”(software reusability) 的思想。的思想。5. 多態性多態性如果有幾個相似而不完全相同的對象,有時人們要如果有幾個相似而不完全相同的對象,有時人們要求在向它們發出同一個消息時,它們的反應各不相求在向它們發出同一個消息時,它們的反應各不相同,分別執行不同的操作。這種情況
12、就是同,分別執行不同的操作。這種情況就是多態現象多態現象。如,在如,在windows環境下,用鼠標雙擊一個文件對象環境下,用鼠標雙擊一個文件對象(這就是向對象傳送一個消息這就是向對象傳送一個消息),如果對象是一個可,如果對象是一個可執行文件,則會執行此程序,如果對象是一個文本執行文件,則會執行此程序,如果對象是一個文本文件,則啟動文本編輯器并打開該文件。文件,則啟動文本編輯器并打開該文件。在在c+中,所謂多態性中,所謂多態性(polymorphism)是指:是指: 由繼由繼承而產生的相關的不同的類,其對象對同一消息會承而產生的相關的不同的類,其對象對同一消息會作出不同的響應。作出不同的響應。多
13、態性是面向對象程序設計的一多態性是面向對象程序設計的一個重要特征,能增加程序的靈活性。個重要特征,能增加程序的靈活性。傳統的面向過程程序設計是圍繞功能進行的,用一傳統的面向過程程序設計是圍繞功能進行的,用一個函數實現一個功能。所有的數據都是公用的,一個函數實現一個功能。所有的數據都是公用的,一個函數可以使用任何一組數據,而一組數據又能被個函數可以使用任何一組數據,而一組數據又能被多個函數所使用多個函數所使用(見圖(見圖8.3)。)。 圖圖8.38.1.2 面向對象程序設計的特點面向對象程序設計的特點面向對象程序設計采取的是另外一種思路。它面對面向對象程序設計采取的是另外一種思路。它面對的是一個
14、個對象。實際上,每一組數據都是有特定的是一個個對象。實際上,每一組數據都是有特定的用途的,是某種操作的對象。也就是說,一組操的用途的,是某種操作的對象。也就是說,一組操作調用一組數據。作調用一組數據。程序設計者的任務包括程序設計者的任務包括兩個方面兩個方面: 一一 設計所需的各種類和對象,即決定把哪些數據設計所需的各種類和對象,即決定把哪些數據和操作封裝在一起;和操作封裝在一起;二二 考慮怎樣向有關對象發送消息,以完成所需的考慮怎樣向有關對象發送消息,以完成所需的任務。任務。 類是類是c+中十分重要的概念,它是實現面向對象程中十分重要的概念,它是實現面向對象程序設計的基礎。類是所有面向對象的語
15、言的共同特序設計的基礎。類是所有面向對象的語言的共同特征,所有面向對象的語言都提供了這種類型。征,所有面向對象的語言都提供了這種類型。 在本章到第在本章到第10章將介紹章將介紹基于對象的程序設計基于對象的程序設計。包。包括括類和對象的概念類和對象的概念、類的機制和聲明類的機制和聲明、類對象的定類對象的定義與使用義與使用等。這是面向對象的程序設計的基礎。等。這是面向對象的程序設計的基礎。8.1.3 類和對象的作用類和對象的作用隨著軟件規模的迅速增大,軟件人員面臨的問題十隨著軟件規模的迅速增大,軟件人員面臨的問題十分復雜。需要規范整個軟件開發過程,明確軟件開分復雜。需要規范整個軟件開發過程,明確軟
16、件開發過程中每個階段的任務,在保證前一個階段工作發過程中每個階段的任務,在保證前一個階段工作的正確性的情況下,再進行下一階段的工作。這就的正確性的情況下,再進行下一階段的工作。這就是軟件工程學需要研究和解決的問題。是軟件工程學需要研究和解決的問題。面向對象的軟件工程包括以下幾個部分面向對象的軟件工程包括以下幾個部分: 8.1.4 面向對象的軟件開發面向對象的軟件開發1. 面向對象分析面向對象分析(object oriented analysis,ooa) 軟件工程中的系統分析階段,系統分析員要和用戶軟件工程中的系統分析階段,系統分析員要和用戶結合在一起,做出需求分析,結合在一起,做出需求分析,
17、 概括出系統動能和概括出系統動能和任務。任務。面向對象的分析,面向對象的分析, 按照面向對象的概念和方法,按照面向對象的概念和方法,在在 歸納出有關的對象歸納出有關的對象(包括對象的屬性和行為包括對象的屬性和行為)以以及對象之間的聯系,并將具有相同屬性和行為的對及對象之間的聯系,并將具有相同屬性和行為的對象用一個類象用一個類(class)來表示。建立一個能反映真實工來表示。建立一個能反映真實工作情況的需求模型。作情況的需求模型。2. 面向對象設計面向對象設計(object oriented design,ood)根據面向對象分析階段形成的需求模型,對每一部根據面向對象分析階段形成的需求模型,對
18、每一部分分別進行具體的設計,首先是進行類的設計,類分分別進行具體的設計,首先是進行類的設計,類的設計可能包含多個層次的設計可能包含多個層次(利用繼承與派生利用繼承與派生)。然后。然后以這些類為基礎提出程序設計的思路和方法,包括以這些類為基礎提出程序設計的思路和方法,包括對算法的設計。對算法的設計。 3. 面向對象編程面向對象編程(object oriented programming,oop)根據面向對象設計的結果,用一種計算機語言把它根據面向對象設計的結果,用一種計算機語言把它寫成程序,顯然應當選用面向對象的計算機語言寫成程序,顯然應當選用面向對象的計算機語言(例如例如c+),否則無法實現面
19、向對象設計的要求。,否則無法實現面向對象設計的要求。4. 面向對象測試面向對象測試(object oriented test,oot)在寫好程序后交給用戶使用前,必須對程序進行嚴在寫好程序后交給用戶使用前,必須對程序進行嚴格的測試。測試的目的是發現程序中的錯誤并改正格的測試。測試的目的是發現程序中的錯誤并改正它。它。 5. 面向對象維護面向對象維護(object oriented soft maintenance,oosm)因為對象的封裝性,修改一個對象對其他對象影響因為對象的封裝性,修改一個對象對其他對象影響很小。利用面向對象的方法維護程序,大大提高了很小。利用面向對象的方法維護程序,大大提
20、高了軟件維護的效率。軟件維護的效率。每一個實體都是對象。有一些對象是具有相同的結構和特每一個實體都是對象。有一些對象是具有相同的結構和特性的。每個對象都屬于一個特定的類型。性的。每個對象都屬于一個特定的類型。在在c+中對象的類型稱為中對象的類型稱為類類(class)。類代表了某一批對象的類代表了某一批對象的共性和特征。共性和特征。前面已說明:前面已說明: 類是對象的抽象,而對象是類類是對象的抽象,而對象是類的具體實例的具體實例(instance)。在在c+中也是先聲明一個類類型,然后用它去定義若干個同中也是先聲明一個類類型,然后用它去定義若干個同類型的對象。對象就是類類型的一個變量。可以說類是
21、對類型的對象。對象就是類類型的一個變量。可以說類是對象的模板,是用來定義對象的一種抽象類型。象的模板,是用來定義對象的一種抽象類型。類是抽象的,不占用內存,而對象是具體的,占用存儲空類是抽象的,不占用內存,而對象是具體的,占用存儲空間。間。8.2 類的聲明和對象的定義類的聲明和對象的定義 8.2.1 類和對象的關系類和對象的關系類是用戶自己指定的類型。如果程序中要用到類類類是用戶自己指定的類型。如果程序中要用到類類型,必須自己根據需要進行聲明,或者使用別人已型,必須自己根據需要進行聲明,或者使用別人已設計好的類。設計好的類。在在c+中聲明一個類類型和聲明一個結構體類型是中聲明一個類類型和聲明一
22、個結構體類型是相似的。相似的。下面是聲明一個結構體類型的方法:下面是聲明一個結構體類型的方法: struct student /聲明了一個名為聲明了一個名為student的結構體類型的結構體類型 int num;char name20;char sex;student stud1,stud2; /定義了兩個結構體變量定義了兩個結構體變量stud1和和stud28.2.2 聲明類類型聲明類類型它只包括數據,沒有包括操作。現在聲明一個類:它只包括數據,沒有包括操作。現在聲明一個類: class student /以以class開頭開頭 int num;char name20; char sex;
23、/以上以上3行是數據成員行是數據成員 void display( ) /這是成員函數這是成員函數coutnum:numendl;coutname:nameendl; coutsex:sexendl; /以上以上4行是函數中的操作語句行是函數中的操作語句 ;student stud1,stud2; /定義了兩個定義了兩個student 類的對象類的對象stud1和和stud2 可以看到聲明類的方法是由聲明結構體類型的方法可以看到聲明類的方法是由聲明結構體類型的方法發展而來的。發展而來的。類類(class)就是對象的類型。實際上,類是一種廣義就是對象的類型。實際上,類是一種廣義的數據類型。的數據類
24、型。類這種數據類型中的數據既包含數據,類這種數據類型中的數據既包含數據,也包含操作數據的函數。也包含操作數據的函數。不能把類中的全部成員與外界隔離,不能把類中的全部成員與外界隔離,一般是把數據一般是把數據隱蔽起來,而把成員函數作為對外界的接口。隱蔽起來,而把成員函數作為對外界的接口。可以將上面類的聲明改為可以將上面類的聲明改為class student /聲明類類型聲明類類型 private: /聲明以下部分為私有的聲明以下部分為私有的int num;char name20; char sex; public: /聲明以下部分為公用的聲明以下部分為公用的void display( ) cout
25、num:numendl;coutname:nameendl;coutsex:sexendl; ;student stud1,stud2; /定義了兩個定義了兩個student 類的對象類的對象如果在類的定義中既不指定如果在類的定義中既不指定private,也不指定,也不指定public,則系統就默認為是私有的。,則系統就默認為是私有的。歸納以上對類類型的聲明,可得到其一般形式如下:歸納以上對類類型的聲明,可得到其一般形式如下: class 類名類名 private:私有的數據和成員函數私有的數據和成員函數; public:公用的數據和成員函數公用的數據和成員函數;private和和public
26、稱為成員訪問限定符稱為成員訪問限定符(member access specifier)。除了除了private和和public之外,還有一種成員訪問限定之外,還有一種成員訪問限定符符protected(受保護的受保護的),用用protected聲明的成員稱聲明的成員稱為受保護的成員,它不能被類外訪問為受保護的成員,它不能被類外訪問(這點與私有這點與私有成員類似成員類似),但可以被派生類的成員函數訪問,但可以被派生類的成員函數訪問。如果在類體中既不寫如果在類體中既不寫private,又不寫,又不寫public,系統,系統默認為默認為private。在一個類體中,關鍵字在一個類體中,關鍵字priv
27、ate和和public可以分別出可以分別出現多次。每個部分的有效范圍到出現另一個訪問限現多次。每個部分的有效范圍到出現另一個訪問限定符或類體結束時定符或類體結束時(最后一個右花括號最后一個右花括號)為止。為止。但是但是為了使程序清晰,應該養成這樣的習慣:為了使程序清晰,應該養成這樣的習慣: 使每一使每一種成員訪問限定符在類定義體中只出現一次。種成員訪問限定符在類定義體中只出現一次。 在在c+程序中,經常可以看到類。程序中,經常可以看到類。為了用戶方便為了用戶方便,常用的常用的c+編譯系統往往向用戶提供類庫編譯系統往往向用戶提供類庫(但不屬但不屬于于c+語言的組成部分語言的組成部分),內裝常用的
28、基本的類,內裝常用的基本的類,供用戶使用。不少用戶也把自己或本單位經常用到供用戶使用。不少用戶也把自己或本單位經常用到的類放在一個專門的類庫中,需要用時直接調用,的類放在一個專門的類庫中,需要用時直接調用,這樣就減少了程序設計的工作量。這樣就減少了程序設計的工作量。8.2.2節的程序段中,最后一行用已聲明的節的程序段中,最后一行用已聲明的student類來定義對象,這種方法是很容易理解的。經過定類來定義對象,這種方法是很容易理解的。經過定義后,義后,stud1和和stud2就成為具有就成為具有student類特征的對類特征的對象。象。stud1和和stud2這兩個對象都分別包括這兩個對象都分別
29、包括student類類中定義的數據和函數。中定義的數據和函數。定義對象也可以有幾種方法。定義對象也可以有幾種方法。8.2.3 定義對象的方法定義對象的方法1. 先聲明類類型,然后再定義對象先聲明類類型,然后再定義對象前面用的就是這種方法,如前面用的就是這種方法,如student stud1,stud2; /student是已經聲明的類類型是已經聲明的類類型在在c+中,聲明了類類型后,定義對象如下。中,聲明了類類型后,定義對象如下。類名類名 對象名對象名 student stud1,stud2;直接用類名定義對象。這兩種方法是等效的。直接用類名定義對象。這兩種方法是等效的。 2. 在聲明類類型的
30、同時定義對象在聲明類類型的同時定義對象class student /聲明類類型聲明類類型 public: /先聲明公用部分先聲明公用部分 void display( ) coutnum:numendl;coutname:nameendl;coutsex:sexendl; private: /后聲明私有部分后聲明私有部分int num;char name20; char sex; stud1,stud2; /定義了兩個定義了兩個student類的對象類的對象在定義在定義student類的同時,定義了兩個類的同時,定義了兩個student 類的類的對象。對象。3. 不出現類名,直接定義對象不出現類
31、名,直接定義對象class /無類名無類名private: /聲明以下部分為私有的聲明以下部分為私有的 public: /聲明以下部分為公用的聲明以下部分為公用的 stud1,stud2; /定義了兩個無類名的定義了兩個無類名的類對象類對象直接定義對象,在直接定義對象,在c+中是合法的、允許的。中是合法的、允許的。前面講結構體時也有過類似的定義方法,前面講結構體時也有過類似的定義方法,不提倡用不提倡用類的成員函數類的成員函數(簡稱類函數簡稱類函數)是函數的一種,它的用是函數的一種,它的用法和作用和第法和作用和第4章介紹過的函數基本上是一樣的,章介紹過的函數基本上是一樣的,它也有返回值和函數類型
32、,它也有返回值和函數類型,它與一般函數的區別只它與一般函數的區別只是:是: 它是屬于一個類的成員,出現在類體中。它它是屬于一個類的成員,出現在類體中。它可以被指定為可以被指定為private(私有的私有的)、public(公用的公用的)或或protected(受保護的受保護的)。在使用類函數時,要在使用類函數時,要注意調注意調用它的權限用它的權限(它能否被調用它能否被調用)以及它的以及它的作用域作用域(函數能函數能使用什么范圍中的數據和函數使用什么范圍中的數據和函數)。8.3 類的成員函數類的成員函數 8.3.1 成員函數的性質成員函數的性質 私有的成員函數只能被本類中的其他成員函數所私有的成
33、員函數只能被本類中的其他成員函數所調用,而不能被類外調用。調用,而不能被類外調用。成員函數可以訪問本類中任何成員成員函數可以訪問本類中任何成員(包括私有的和包括私有的和公用的公用的),可以引用在本作用域中有效的數據,可以引用在本作用域中有效的數據。一般的做法是將需要被外界調用的成員函數指定為一般的做法是將需要被外界調用的成員函數指定為public,它們是類的對外接口。,它們是類的對外接口。但應注意,但應注意,并非要并非要求把所有成員函數都指定為求把所有成員函數都指定為public。有的函數并不有的函數并不是準備為外界調用的,而是為本類中的成員函數所是準備為外界調用的,而是為本類中的成員函數所調
34、用的,就應該將它們指定為調用的,就應該將它們指定為private。這種函數的。這種函數的作用是支持其他函數的操作,是類中其他成員的作用是支持其他函數的操作,是類中其他成員的工工具函數具函數,類外用戶不能調用這些私有的工具函數。,類外用戶不能調用這些私有的工具函數。 在前面已經看到成員函數是在類體中定義的。也可在前面已經看到成員函數是在類體中定義的。也可以在類體中只寫成員函數的聲明,而在類的外面進以在類體中只寫成員函數的聲明,而在類的外面進行函數定義。如行函數定義。如 class student public:void display( ); /公用成員函數原型聲明公用成員函數原型聲明priva
35、te:int num;string name; char sex; /以上以上3行是私有數據成員行是私有數據成員 ;void student display( ) /在類外定義在類外定義display類函數類函數coutnum:numendl; /函數體函數體coutname:nameendl; coutsex:sexendl; student stud1,stud2; /定義兩個類對象定義兩個類對象8.3.2 在類外定義成員函數在類外定義成員函數注意:注意: 在類體中直接定義函數時,不需要在函數在類體中直接定義函數時,不需要在函數名前面加上類名,因為函數屬于哪一個類是不言而名前面加上類名,因
36、為函數屬于哪一個類是不言而喻的。喻的。成員函數在類外定義時,必須在函數名前面成員函數在類外定義時,必須在函數名前面加上類名,予以限定加上類名,予以限定(qualifed),“ ”是作用域限是作用域限定符定符(field qualifier)或稱作用域運算符,或稱作用域運算符,用它聲明用它聲明函數是屬于哪個類的。函數是屬于哪個類的。如果在作用域運算符如果在作用域運算符“ ”的前面沒有類名,或者的前面沒有類名,或者函數名前面既無類名又無作用域運算符函數名前面既無類名又無作用域運算符“ ”,如,如 display( ) 或或 display( )表示表示display函數不屬于任何類,這個函數不是成
37、員函數不屬于任何類,這個函數不是成員函數,而是全局函數,即非成員函數的一般普通函函數,而是全局函數,即非成員函數的一般普通函數。數。類函數必須先在類體中作原型聲明,然后在類外定類函數必須先在類體中作原型聲明,然后在類外定義,也就是說類體的位置應在函數定義之前,否則義,也就是說類體的位置應在函數定義之前,否則編譯時會出錯編譯時會出錯。雖然函數在類的外部定義,但在調用成員函數時會雖然函數在類的外部定義,但在調用成員函數時會根據在類中聲明的函數原型找到函數的定義(函數根據在類中聲明的函數原型找到函數的定義(函數代碼),從而執行該函數。代碼),從而執行該函數。在類的內部對成員函數作聲明,而在類體外定義
38、成在類的內部對成員函數作聲明,而在類體外定義成員函數,這是程序設計的一種良好習慣。員函數,這是程序設計的一種良好習慣。如果一個函數,函數體小,可以在類中定義,函數如果一個函數,函數體小,可以在類中定義,函數體大,應該在類外進行定義。體大,應該在類外進行定義。關于關于內置內置(inline)函數函數,已在第,已在第4章第章第4.5節中作過介節中作過介紹。類的成員函數也可以指定為內置函數。紹。類的成員函數也可以指定為內置函數。在類體中定義的成員函數的規模一般都很小,而系在類體中定義的成員函數的規模一般都很小,而系統調用函數的過程所花費的時間開銷相對是比較大統調用函數的過程所花費的時間開銷相對是比較
39、大的。的。調用一個函數的時間開銷遠遠大于小規模函數調用一個函數的時間開銷遠遠大于小規模函數體中全部語句的執行時間。體中全部語句的執行時間。為了減少時間開銷,如為了減少時間開銷,如果在類體中定義的成員函數中不包括循環等控制結果在類體中定義的成員函數中不包括循環等控制結構,構,c+系統會自動將它們作為內置系統會自動將它們作為內置(inline)函數來函數來處理。也就是說,在程序調用這些成員函數時,并處理。也就是說,在程序調用這些成員函數時,并不是真正地執行函數的調用過程不是真正地執行函數的調用過程(如保留返回地址如保留返回地址等處理等處理),而是把函數代碼嵌入程序的調用點。這,而是把函數代碼嵌入程
40、序的調用點。這樣可以大大減少調用成員函數的時間開銷。樣可以大大減少調用成員函數的時間開銷。8.3.3 inline 成員函數成員函數c+要求對一般的內置函數要用關鍵字要求對一般的內置函數要用關鍵字inline聲明,聲明,但對類內定義的成員函數,可以省略但對類內定義的成員函數,可以省略inline,因為,因為這些成員函數已被隱含地指定為內置函數。這些成員函數已被隱含地指定為內置函數。如如 class student public: void display( ) coutnum:numendl;coutname:nameendl; coutsex:sexendl; private:int num
41、;string name; char sex;其中第其中第3行行void display( )也可以寫成也可以寫成inline void display( )將將display函數顯式地聲明為內置函數。以上兩種寫函數顯式地聲明為內置函數。以上兩種寫法是等效的。對在類體內定義的函數,一般都省寫法是等效的。對在類體內定義的函數,一般都省寫inline。應該注意的是:應該注意的是: 如果成員函數不在類體內定義,如果成員函數不在類體內定義,而在類體外定義,系統并不把它默認為內置而在類體外定義,系統并不把它默認為內置(inline)函數,調用這些成員函數的過程和調用一般函數的函數,調用這些成員函數的過程
42、和調用一般函數的過程是相同的。如果想將這些成員函數指定為內置過程是相同的。如果想將這些成員函數指定為內置函數,應當函數,應當用用inline作顯式聲明作顯式聲明。如如class student public:inline void display( ); /聲明此成員函數為內置函數聲明此成員函數為內置函數private:int num;string name; char sex; ;inline void student display( ) / 在類外定義在類外定義display函數為內置函數函數為內置函數coutnum:numendl; coutname:nameendl; coutsex
43、:sexabc;可以用下面的語句來輸出該類對象所占用的字節數可以用下面的語句來輸出該類對象所占用的字節數:coutsizeof(time)endl;輸出的值是輸出的值是12。這就證明了一個對象所占的空間大。這就證明了一個對象所占的空間大小只取決于該對象中數據成員所占的空間,而與成小只取決于該對象中數據成員所占的空間,而與成員函數無關。員函數無關。需要注意的是:需要注意的是: 雖然調用不同對象的成員函數時雖然調用不同對象的成員函數時都是執行同一段函數代碼,但是執行結果一般是不都是執行同一段函數代碼,但是執行結果一般是不相同的。不同的對象使用的是同一個函數代碼段,相同的。不同的對象使用的是同一個函
44、數代碼段,它怎么能夠分別對不同對象中的數據進行操作呢?它怎么能夠分別對不同對象中的數據進行操作呢?原來原來c+為此專門設立了一個名為為此專門設立了一個名為this的指針,用的指針,用來指向不同的對象來指向不同的對象。需要說明:需要說明: (1) 不論成員函數在類內定義還是在類外定義,成不論成員函數在類內定義還是在類外定義,成員函數的代碼段都用同一種方式存儲。員函數的代碼段都用同一種方式存儲。(2) 不要將成員函數的這種存儲方式和不要將成員函數的這種存儲方式和inline(內置內置)函數的概念混淆。函數的概念混淆。(3) 應當說明:應當說明: 常說的常說的“某某對象的成員函數某某對象的成員函數”
45、,是從邏輯的角度而言的,而成員函數的存儲方式,是從邏輯的角度而言的,而成員函數的存儲方式,是從物理的角度而言的,二者是不矛盾的。是從物理的角度而言的,二者是不矛盾的。在程序中經常需要訪問對象中的成員。訪問對象中在程序中經常需要訪問對象中的成員。訪問對象中的成員可以有的成員可以有3種方法種方法: 通過通過對象名對象名和和成員運算符成員運算符訪問對象中的成員訪問對象中的成員;通過通過指向對象的指針指向對象的指針訪問對象中的成員訪問對象中的成員;通過通過對象的引用變量對象的引用變量訪問對象中的成員。訪問對象中的成員。8.4 對象成員的引用對象成員的引用例如在程序中可以寫出以下語句:例如在程序中可以寫
46、出以下語句: stud1.num=1001; /假設假設num已定義為公用的整型數據成員已定義為公用的整型數據成員表示將整數表示將整數1001賦給對象賦給對象stud1中的數據成員中的數據成員num。其中其中“.”是成員運算符是成員運算符,用來對成員進行限定,指,用來對成員進行限定,指明所訪問的是哪一個對象中的成員。注意不能只寫明所訪問的是哪一個對象中的成員。注意不能只寫成員名而忽略對象名。成員名而忽略對象名。訪問對象中成員的一般形式為訪問對象中成員的一般形式為對象名對象名.成員名成員名不僅可以在類外引用對象的公用數據成員,而且還不僅可以在類外引用對象的公用數據成員,而且還可以調用對象的公用成
47、員函數可以調用對象的公用成員函數,但同樣必須指出對,但同樣必須指出對象名,如象名,如8.4.1 通過對象名和成員運算符訪問對象中的成通過對象名和成員運算符訪問對象中的成員員stud1.display( ); /正確,調用對象正確,調用對象stud1的公用成員函數的公用成員函數display( ); /錯誤,錯誤,沒有指明是哪一個對象的沒有指明是哪一個對象的display函數函數由于沒有指明對象名,編譯時把由于沒有指明對象名,編譯時把display作為普通函作為普通函數處理。數處理。應該應該注意注意所訪問的成員是所訪問的成員是公用的公用的(public)還是私有還是私有的的(private)。只
48、能訪問只能訪問public成員,而不能訪問成員,而不能訪問private成員,成員,如果已定義如果已定義num為私有數據成員,下為私有數據成員,下面的語句是錯誤的:面的語句是錯誤的: stud1.num=10101; /num是私有數據成員,不能被外界引用是私有數據成員,不能被外界引用 在類外只能調用公用的成員函數。在一個類中應當在類外只能調用公用的成員函數。在一個類中應當至少有一個公用的成員函數,作為至少有一個公用的成員函數,作為對外的接口對外的接口,否,否則就無法對對象進行任何操作。則就無法對對象進行任何操作。在第在第7章第章第7.1.5節中介紹了指向結構體變量的指針,節中介紹了指向結構體
49、變量的指針,可以通過指針引用結構體中的成員。用指針訪問對可以通過指針引用結構體中的成員。用指針訪問對象中的成員的方法與此類似。如果有以下程序段:象中的成員的方法與此類似。如果有以下程序段: class timepublic: /數據成員是公用的數據成員是公用的int hour;int minute;time t,*p; /定義對象定義對象t和指針變量和指針變量pp=&t; /使使p指向對象指向對象tcouthour; /輸出輸出p指向的對象中的成員指向的對象中的成員hour在在p指向指向t的前提下,的前提下,p-hour,(*p).hour和和t.hour三三者等價。者等價。8.4.2
50、 通過指向對象的指針訪問對象中的成員通過指向對象的指針訪問對象中的成員如果為一個對象定義了一個引用變量,它們是共占如果為一個對象定義了一個引用變量,它們是共占同一段存儲單元的,實際上它們是同一個對象,只同一段存儲單元的,實際上它們是同一個對象,只是用不同的名字表示而已。是用不同的名字表示而已。因此完全可以通過引用因此完全可以通過引用變量來訪問對象中的成員。變量來訪問對象中的成員。如果已聲明了如果已聲明了time類,并有以下定義語句:類,并有以下定義語句: time t1; /定義對象定義對象t1time &t2=t1; /定義定義time類引用變量類引用變量t2,并使之初始化為,并使之
51、初始化為t1coutt2.hour; /輸出對象輸出對象t1中的成員中的成員hour由于由于t2與與t1共占同一段存儲單元共占同一段存儲單元(即即t2是是t1的別名的別名),因此因此t2.hour就是就是t1.hour。本章第本章第8.6節的例節的例8.2中的程序中的程序(b),介紹的是引用變量介紹的是引用變量作為形參的情況,讀者可以參考。作為形參的情況,讀者可以參考。8.4.3 通過對象的引用變量來訪問對象中的成員通過對象的引用變量來訪問對象中的成員在聲明了一個類以后,用戶主要是通過調用公用的在聲明了一個類以后,用戶主要是通過調用公用的成員函數來實現類提供的功能成員函數來實現類提供的功能(例
52、如對數據成員設例如對數據成員設置值,顯示數據成員的值,對數據進行加工等置值,顯示數據成員的值,對數據進行加工等)。因此,公用成員函數是用戶使用類的公用接口因此,公用成員函數是用戶使用類的公用接口(public interface),或者說是類的對外接口。,或者說是類的對外接口。8.5 類的封裝性和信息隱蔽類的封裝性和信息隱蔽 8.5.1 公用接口與私有實現的分離公用接口與私有實現的分離當然并不一定要把所有成員函數都指定為當然并不一定要把所有成員函數都指定為public(公公用用)的,但這時這些成員函數就不是公用接口了。的,但這時這些成員函數就不是公用接口了。在類外雖然不能直接訪問私有數據成員,
53、但可以通在類外雖然不能直接訪問私有數據成員,但可以通過調用公用成員函數來引用甚至修改私有數據成員過調用公用成員函數來引用甚至修改私有數據成員。用戶可以調用公用成員函數來實現某些功能,而這用戶可以調用公用成員函數來實現某些功能,而這些功能是在聲明類時已指定的,用戶可以使用它們些功能是在聲明類時已指定的,用戶可以使用它們而不應改變它們。實際上用戶往往并不關心這些功而不應改變它們。實際上用戶往往并不關心這些功能是如何實現的細節,而只需知道調用哪個函數會能是如何實現的細節,而只需知道調用哪個函數會得到什么結果,能實現什么功能即可。得到什么結果,能實現什么功能即可。 可以看到:可以看到: 類中被操作的數
54、據是私有的,實現的類中被操作的數據是私有的,實現的細節對用戶是隱蔽的,這種實現稱為私有實現細節對用戶是隱蔽的,這種實現稱為私有實現(private implementation)。這種。這種“類的公用接口與類的公用接口與私有實現的分離私有實現的分離”形成了信息隱蔽。形成了信息隱蔽。軟件工程的一個最基本的原則就是軟件工程的一個最基本的原則就是將接口與實現分將接口與實現分離離,信息隱蔽是軟件工程中一個非常重要的概念。,信息隱蔽是軟件工程中一個非常重要的概念。它的它的好處在于好處在于: (1) 如果想修改或擴充類的功能,只需修改本類中如果想修改或擴充類的功能,只需修改本類中有關的數據成員和與它有關的
55、成員函數,程序中類有關的數據成員和與它有關的成員函數,程序中類外的部分可以不必修改。外的部分可以不必修改。(2) 如果在編譯時發現類中的數據讀寫有錯,不必如果在編譯時發現類中的數據讀寫有錯,不必檢查整個程序,只需檢查本類中訪問這些數據的少檢查整個程序,只需檢查本類中訪問這些數據的少數成員函數。數成員函數。在面向對象的程序開發中,在面向對象的程序開發中,一般做法是將類的聲明一般做法是將類的聲明(其中包含成員函數的聲明其中包含成員函數的聲明)放在指定的頭文件中,放在指定的頭文件中,用戶如果想用該類,只要把有關的頭文件包含進來用戶如果想用該類,只要把有關的頭文件包含進來即可,不必在程序中重復書寫類的
56、聲明,以減少工即可,不必在程序中重復書寫類的聲明,以減少工作量,節省篇幅,提高編程的效率。作量,節省篇幅,提高編程的效率。由于在頭文件中包含了類的聲明,因此在程序中就由于在頭文件中包含了類的聲明,因此在程序中就可以用該類來定義對象。由于在類體中包含了對成可以用該類來定義對象。由于在類體中包含了對成員函數的聲明,在程序中就可以調用這些對象的公員函數的聲明,在程序中就可以調用這些對象的公用成員函數用成員函數。為了實現上一節所敘述的信息隱蔽,。為了實現上一節所敘述的信息隱蔽,對類成員函數的定義一般不放在頭文件中,而另外對類成員函數的定義一般不放在頭文件中,而另外放在一個文件中。放在一個文件中。8.5
57、.2 類聲明和成員函數定義的分離類聲明和成員函數定義的分離例如,可以分別寫兩個文件:例如,可以分別寫兩個文件: /student.h (這是頭文件,在此文件中進行類的聲明這是頭文件,在此文件中進行類的聲明)class student /類聲明類聲明 public:void display( ); /公用成員函數原型聲明公用成員函數原型聲明private:int num; char name20; char sex; ;/student.cpp /在此文件中進行函數的定義在此文件中進行函數的定義#include #include student.h /不要漏寫此行,否則編譯通不過不要漏寫此行,否
58、則編譯通不過void student display( ) /在類外定義在類外定義display類函數類函數coutnum:numendl; coutname:nameendl; coutsex:sexendl; 為了組成一個完整的源程序,還應當有包括主函數為了組成一個完整的源程序,還應當有包括主函數的源文件:的源文件: /main.cpp 主函數模塊主函數模塊#include #include student.h /將類聲明頭文件包含進來將類聲明頭文件包含進來int main( )student stud; /定義對象定義對象stud.display( ); /執行執行stud對象的對象的d
59、isplay函數函數return 0;這是一個包括這是一個包括3個文件的程序,組成兩個文件模塊:個文件的程序,組成兩個文件模塊: 一個是主模塊一個是主模塊main.cpp,一個是一個是student.cpp。在主。在主模塊中又包含頭文件模塊中又包含頭文件student.h。在預編譯時會將頭在預編譯時會將頭文件文件student.h中的內容取代中的內容取代#include student.h行。行。請注意:請注意: 由于將頭文件由于將頭文件student.h放在用戶當前目放在用戶當前目錄中,因此在文件名兩側用雙撇號包起來錄中,因此在文件名兩側用雙撇號包起來(student.h)而不用尖括號而不用
60、尖括號(),否則編,否則編譯時會找不到此文件。譯時會找不到此文件。圖圖8.6。在運行程序時調用在運行程序時調用stud中的中的display函數,輸出各數函數,輸出各數據成員的值。據成員的值。在實際工作中,并不是將一個類聲明做成一個頭文在實際工作中,并不是將一個類聲明做成一個頭文件,而是將若干個常用的功能相近的類聲明集中在件,而是將若干個常用的功能相近的類聲明集中在一起,形成類庫。一起,形成類庫。類庫有兩種:類庫有兩種:一種是一種是c+編譯系統提供的編譯系統提供的標準類庫標準類庫;一種是用戶根據自己的需要做成的用戶類庫,提供一種是用戶根據自己的需要做成的用戶類庫,提供給自己和自己授權的人使用,這稱為給自己和自己授權的人使用
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T/CIMA 0028-2021手持式數字多用表檢驗規范
- T/CIMA 0021-2020諧波有功電能表檢驗裝置
- T/CIIA 017-2022科學數據安全標準體系
- T/CHTS 20025-2022公路橋梁單元式工字形鋼梳齒型伸縮裝置
- T/CHINABICYCLE 1-2018電動自行車集中充電設施設備技術規范
- T/CHES 43-2020水利水電工程白蟻實時自動化監測預警系統技術規范
- T/CHC 1004.3-2023植物基食品第3部分:肉制品
- T/CGA 42-2023地下黃金礦山巖石力學數據采集技術規范
- T/CECS 10302-2023抗流掛聚氨酯防水涂料
- T/CECS 10295-2023建筑機器人地面清潔機器人
- 租賃換電定制合同協議
- 2025標準技術咨詢服務合同模板
- 慢性腎臟病肌少癥診斷治療與預防專家共識(2024年版)解讀
- 汽車制造業產品質量管理措施
- 科學上海會考試卷及答案
- 中小學校園安全風險防控規范操作手冊與案例分析
- 大模型備案-落實算法安全主體責任基本情況-XX集團有限公司
- 重大危險源安全管理培訓
- 封閉管理的疫情防控課件
- 離婚協議書正規打印(2025年版)
- 世界各地文化創意產業發展報告表
評論
0/150
提交評論