版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第3篇基于對象的程序設計第8章第9章類和對象關于類和對象的進一步第10章運算符重載面類的象程序設計方法概述和對象的定義類的成員函數對象成員的類的封裝性和信息隱蔽類和對象的簡單應用舉例第8章 類和對象8.1 面象程序設計方法概述介紹的是C+在面向過程的程序到目前為止,設計中的應用。對于規(guī)模比較小的程序,編程者可以直接編寫出一個面向過程的程序,詳細地描述每一瞬時的數據結構及對其的操作過程。但是當程序規(guī)模較大時,就顯得力不從心了。C+就是為了解決編寫大程序過程中的而產生的。8.1.1面面象的程序設計象的程序設計的思路和人們日常生活中處理問題的思路是相似的。在自然世界和社會生活中,一個復雜的事物總是由
2、許多部分組成的。當人們生產汽車時,分別設計和制造發(fā)、底盤、車身和,最后把它們組裝在一起。在組裝時,各部分之間有一定的聯系,以便協調工作。這就是面象的程序設計的基本思路。為了進一步說明問題,下面先幾個有關的概念。1. 對象客觀世界中任何一個事物都可以看成一個對象(object)。對象可大可小。對象是系統(tǒng)的基本。任何一個對象都應當具有這兩個要素,即屬性(attribute)和行為(behavior),它能根據外界給的信息進行相應的操作。一個對象往往是由一組屬性和一組行為的。一般來說,凡是具備屬性和行為這兩種要素的,都可以作為對象。在一個系統(tǒng)中的多個對象之間通過一定的相互聯系,如圖8.1示意。要使某
3、一個對象實現某一種行為(即操作),應當向它傳送相應的消息。對象之間就是這樣通過發(fā)送和接收消息互相聯系的。圖8.1圖8.2面象的程序設計采用了以上人們所熟悉的這種思路。使用面象的程序設計方法設計一個復雜的系統(tǒng)時,首要是確定該系統(tǒng)是由哪些對象組成的,并且設計這些對象。在C+中,每個對象都是由數據和函數(即操作代碼)這兩部分組成的,見圖8.2。數據體現了前面提到的“屬性”,如一個三角形對象,它的3個邊長就是它的屬性。函數是用來對數據進行操作的,以便實現某些功能,例如可以通過邊長計算出三角形的面積,并且輸出三角形的邊長和面積。計算三角形面積和輸出有關數據就是前面提到的行為,在程序設計方法中也稱為方法(
4、method)。調用對象中的函數就是向該對象傳送一個消息(message),要求該對象實現某一行為 (功能)。2. 封裝與信息隱蔽可以對一個對象進行封裝處理,把它的一部分屬性和功能對外界甚至是不可知的。,也就是說從外界是看不到的,這樣做的好處是大大降低了操作對象的復雜程度。象程序設計方法的一個重要特點就是“封裝面性” (encapsulation),所謂“封裝”,指兩方面的含義: 一是將有關的數據和操作代碼封裝在一個對象中,形成一個基本,各個對象之間相對獨立,互不干擾。二是將對象中某些部分對外隱蔽,即隱蔽其細節(jié),只留下少量接口,以便與外界聯系,接收外界的消息。這種對外界隱蔽的做法稱為信息隱蔽(
5、imformation hiding)。信息隱蔽還有利于數據安全,防止無關的人了解和修改數據。C+的對象中的函數名就是對象的對外接口,外界可以通過函數名來調用這些函數來實現某些行為(功能)。這些將在以后詳細介紹。3. 抽象在程序設計方法中,常用到抽象(abstraction)這一名詞。抽象的過程是將有關事物的共性歸納、集中的過程。抽象的作用是表示同一類事物的本質。C和C+中的數據類型就是對一批具體的數的抽象。對象是具體存在的,如一個三角形可以作為一個對象,10個不同尺寸的三角形是10個對象。如果這10個三角形對象有相同的屬性和行為,可以將它們抽象為一種類型,稱為三角形類型。在C+中,這種類型就
6、稱為“類(class)”。這10個三角形就是屬于同一“類”的對象。類是對象的抽象,而對象則是類的特例,或者說是類的具體表現形式。4. 繼承與重用開發(fā)中已經建立了一個名為A的“類”,如果在又想另外建立一個名為B的“類”,而后者與前者內容基本相同,只是者的基礎上增加一些屬性和行為,只需在類A的基礎上增加一些新內容即可。這就是面象程序設計中的繼承機制。利用繼承可以簡化程序設計的步驟?!鞍遵R”繼承了“馬”的基本特征,又增加了新的特征 (顏色),“馬”是父類,或稱為基類,“白馬”是從“馬”派生出來的,稱為子類或派生類。C+提供了繼承機制,采用繼承的方法可以很方便地利用一個已有的類建立一個新的類。這就是常
7、說的“重用”(software reusability) 的。5. 多態(tài)性如果有幾個相似而不完全相同的對象,有時人們要 求在向它們發(fā)出同一個消息時,它們的反應各不相 同,分別執(zhí)行不同的操作。這種情況就是多態(tài)現象。如,在Windows環(huán)境下,用鼠標雙擊一個文件對象(這就是象傳送一個消息),如果對象是一個可執(zhí)行文件,則會執(zhí)行此程序,如果對象是一個文本文件,則啟動文本編輯器并打開該文件。在C+中,所謂多態(tài)性(polymorphism)是指:承而產生的相關的不同的類,其對象對同一消息會作出不同的響應。多態(tài)性是面象程序設計的一個重要特征,能增加程序的靈活性。8.1.2 面象程序設計的特點傳統(tǒng)的面向過程程
8、序設計是圍繞功能進行的,用一個函數實現一個功能。所有的數據都是公用的,一個函數可以使用任何一組數據,而一組數據又能被多個函數所使用(見圖8.3)。圖8.3面象程序設計采取的是另外一種思路。它面對的是一個個對象。實際上,每一組數據都是有特定的用途的,是某種操作的對象。也就是說,一組操作調用一組數據。程序設計者的任務包括兩個方面: 一是設計所需的各種類和對象,即決定把哪些數據和操作封裝在一起;二是考慮怎樣向有關對象發(fā)送消息,以完成所需的任務。這時他如同一個總調度,不斷地向各個對象發(fā)出命令,讓這些對象活動起來(或者說激活這些對象),完成自己職責范圍內的工作。各個對象的操作完成了,整體任務也就完成了。
9、顯然,對一個大型任務來說,面象程序設計方法是十分有效的,它能大大降低程序設計減少出錯機會。的工作難度,8.1.3 類和對象的作用類是C+中十分重要的概念,它是實現面象程序設計的基礎。類是所有面象的語言的共同特征,所有面象的語言都提供了這種類型。一個有一定規(guī)模的C+程序是由許多類所的。C+支持面向過程的程序設計,也支持基于對象的程序設計,又支持面象的程序設計。在本章到第10章將介紹基于對象的程序設計。包括類和對象的概念、類的機制和、類對象的定義與使用等。這是面象的程序設計的基礎?;趯ο缶褪腔陬悺Ec面向過程的程序不同,基于對象的程序是以類和對象為基礎的,程序的操作是圍繞對象進行的。在此基礎上利
10、用了繼承機制和象的程序設計(有時不細分象程序設計,而把二者多態(tài)性,就成為面基于對象程序設計和面象的程序設計)。合稱為面基于對象程序設計所面對的是一個個對象。所有的數據分別屬于不同的對象。在面向過程的結構化程序設計中,人們常使用這樣的公式來表述程序:程序=算法數據結構算法和數據結構兩者是互相獨立、分開設計的,面向過程的程序設計是以算法為主體的。在實踐中人們逐漸認識到算法和數據結構是互相緊密聯系不可分的,應當以一個算法對應一組數據結構,而不宜提倡一個算法對應多組數據結構,以及一組數據結構對應多個算法。基于對象和面象程序設計就是把一個算法和一組數據結構封裝在一個對象中。因此,就形成了新的觀念:對象
11、= 算法 數據結構程序 = (對象+對象+對象+) + 消息程序 = 對象s + 消息“對象s”表示多個對象。消息的作用就是對對象的控制。程序設計的關鍵是設計好每一個對象,及確或:定向這些對象發(fā)出令,使各對象完成相應操作。8.1.4 面隨著象的開發(fā)規(guī)模的迅速增大,十開分復雜。需要規(guī)范整個開發(fā)過程,明確發(fā)過程中每個階段的任務,在保證前一個階段工作的正確性的情況下,再進行下一階段的工作。這就是面工程學需要研究和解決。象的工程包括以下幾個部分:1. 面象分析(object orientedysis,OOA)工程中的系統(tǒng)分析階段,系統(tǒng)分析員要和用戶結合在一起,對用戶的需求作出精確的分析和明確的描述,從
12、宏觀的角度概括出系統(tǒng)應該做什么(而不是怎么做)。面象的分析,要按照面象的概念和方法,在對任務的分析中,從客觀存在的事物和事物之間的關系,歸納出有關的對象(包括對象的屬性和行為)以及對象之間的聯系,并將具有相同屬性和行為的對象用一個類(class)來表示。建立一個能反映真實工作情況的需求模型。2. 面根據面象設計(object oriented design,OOD)象分析階段形成的需求模型,對每一部分分別進行具體的設計,首先是進行類的設計,類的設計可能包含多個層次(利用繼承與派生)。然后以這些類為基礎提出程序設計的思路和方法,包括對算法的設計。在設計階段,并不牽涉某一種具體的計算機語言,而是用
13、一種更通用的描述工具(如偽代碼或流程圖)來描述。3. 面OOP)根據面象編程(object oriented programming,象設計的結果,用一種計算機語言把它寫成程序,顯然應當選用面(例如C+),否則無法實現面象的計算機語言象設計的要求。4. 面象測試(object oriented test,OOT)在寫好程序后交給用戶使用前,必須對程序進行嚴格的測試。測試的目的是發(fā)現程序中的錯誤并改正它。面象測試是用面象的方法進試,以類作為測試的基本單元。5. 面OOSM)象(object oriented soft maenance,因為對象的封裝性,修改一個對象對其他對象影響很小。利用面的效
14、率。象的方法程序,大大提高了現在設計一個大的,是嚴格按照面象工程的5個階段進行的,這5個階段的工作不是由一個人從頭到尾完成的,而是由不同的人分別完成的。這樣,OOP階段的任務就比較簡單了,程序編寫者只需要根據OOD思路用面象語言編寫的開發(fā)中,OOP只是出程序即可。在一個大型面象開發(fā)過程中的一個很小的部分。如果所處理的是一個較簡單,可以不必嚴格按照以上5個階段進行,往往由程序設計者按照面象的方法進行程序設計,包括類的設計(或選用已有的類)和程序的設計。8.2 類的和對象的定義8.2.1 類和對象的關系每一個實體都是對象。有一些對象是具有相同的結構和特性的。每個對象都屬于一個特定的類型。在C+中對
15、象的類型稱為類(class)。類代表了某一批對象的共性和特征。前面已說明: 類是對象的抽象,而對象是類的具體實例(instance)。正如同結構體類型和結構體變量的關系一樣,人們先一個結構體類型,然后用它去定義結構體變量。同一個結構體類型可以定義出多個不同的結構體變量。在C+中也是先一個類類型,然后用它去定義若干個同類型的對象。對象就是類類型的一個變量??梢哉f類是對象的模板,是用來定義對象的一種抽象類型。類是抽象的,不占用內存,而對象是具體的,占用空間。在一開始時弄清對象和類的關系是十分重要的。8.2.2類類型類是用戶自己指定的類型。如果程序中要用到類類型,必須自己根據需要進行,或者使用別人已
16、設計好的類。C+標準本身并不提供現成的類的名稱、結構和內容。在C+中相似的。下面是struct Student一個類類型和一個結構體類型是一個結構體類型的方法:/了一個名為Student的結構體類型num;char name20; char sex;Student stud1,stud2;/定義了兩個結構體變量stud1和stud2它只包括數據,沒有包括操作。現在一個類:class Student/以class開頭num;char name20; char sex;void display( )/以上3行是數據成員/這是成員函數num:numendl;name:nameendl;sex:sex
17、endl;/以上4行是函數中的操作語句;Student stud1,stud2;/定義了兩個Student 類的對象stud1和stud2可以看到類的方法是由結構體類型的方法發(fā)展而來的??梢钥吹?,類(class)就是對象的類型。實際上,類是一種廣義的數據類型。類這種數據類型中的數據既包含數據,也包含操作數據的函數。不能把類中的全部成員與外界,一般是把數據隱蔽起來,而把成員函數作為對外界的接口。可以將上面類的class Student private:num;char name20; char sex;改為類類型以下部分為私有的/public:void display( )/以下部分為公用的nu
18、m:numendl;name:nameendl;sex:sexendl; ;Student stud1,stud2;/定義了兩個Student 類的對象如果在類的定義中既不指定private,也不指定public,則系統(tǒng)就默認為是私有的。歸納以上對類類型的class 類名 private:私有的數據和成員函數; public:公用的數據和成員函數;private和public稱為成員,到其一般形式如下:限定符(memberacs specifier)。除了private和public之外,還有一種成員符protected(受保護的),用protected限定的成員稱為受保護的成員,它不能被類外
19、(這點與私有成員類似),但可以被派生類的成員函數。為為private的成員和在類類型時,public的成員的次序任意,既可以先出現private部分,也可以先出現public部分。如果在類體中既不 寫關鍵字private,又不寫public,就默認為private。在一個類體中,關鍵字private和public可以分別出現多次。每個部分的有效范圍到出現另一個限定符或類體結束時(最后一個右花括號)為止。但是為了使程序清晰,應該養(yǎng)成這樣的: 使每一種成員限定符在類定義體中只出現一次。在以前的C+程序中,出現private部分,后出現public部分,如上面所示?,F在的C+程序多數先寫public
20、部分,把private部分放在類體的后部。這樣可以使用戶將注意力集中在能被外界調用的成員上,使閱讀者的思路更清晰一些。在C+程序中,經??梢钥吹筋?。為了用戶方便,常用的C+編譯系統(tǒng)往往向用戶提供類庫(但不屬于 C+語言的組成部分),內裝常用的基本的類,供用戶使用。不少用戶也把自己或本經常用到的類放在一個專門的類庫中,需要用時直接調用,這樣就減少了程序設計的工作量。8.2.3 定義對象的方法8.2.2節(jié)的程序段中,最后一行用已的Student類來定義對象,這種方法是很容易理解的。經過定義后,stud1和stud2就成為具有Student類特征的對象。stud1和stud2這兩個對象都分別包括St
21、udent類中定義的數據和函數。定義對象也可以有幾種方法。1. 先類類型,然后再定義對象前面用的就是這種方法,如Student stud1,stud2;/Student是已經的類類型在C+中,了類類型后,定義對象有兩種形式。class 類名 對象名如 class Student stud1,stud2;把class和Student合起來作為一個類名,用來定義對象。類名 對象名如 Student stud1,stud2;直接用類名定義對象。這兩種方法是等效的。第1種方法是從C語言繼承下來的,第2種方法是C+的特色,顯然第2種方法更為簡捷方便。2. 在class Student public:vo
22、id display( )類類型的同時定義對象/類類型公用部分/先coutnnum:numendl;name:nameendl; coutsex:sexendl; private:num;char name20; char sex;stud1,stud2;/后私有部分/定義了兩個Student類的對象在定義Student類的同時,定義了兩個Student 類的對象。3. 不出現類名,直接定義對象classprivate:public:stud1,stud2;/無類名/以下部分為私有的/以下部分為公用的/定義了兩個無類名的類對象直接定義對象,在C+中是合法的、允許的,但卻很少用,也不提倡用。在實
23、際的程序開發(fā)中,一般都采用上面3種方法中的第1種方法。在小型程序中的類只用于本程序時,也可以用第2種方或所法。在定義一個對象時,編譯系統(tǒng)會為這個對象分配存儲空間,以存放對象中的成員。8.2.4 類和結構體類型的異同C+增加了class類型后,仍保留了結構體類型 (struct),而且把它的功能也擴展了。C+允許用 struct來定義一個類型。如可以將前面用關鍵字class的類類型改為用關鍵字struct:struct Studentprivate:num;char name20; char sex; public:void display( )/用關鍵字struct來 以下部分為私有的一個類類
24、型/以下3行為數據成員/以下部分為公用的/成員函數num:numendl;name:nameendl; c utsex:sexendl; ;Student stud1,stud2;/定義了兩個Student類的對象為了使結構體類型也具有封裝的特征,C+不是簡單地繼承C的結構體,而是使它也具有類的特點,以便于用于面象程序設計。用struct的結構體類型實際上也就是類。用struct public的的類,如果對其成員不作pprirviavtaet或e,系統(tǒng)將其默認為public。如果想分別指定私有成員和公用成員,則應用private或public作顯式 private或public。而用class
25、定義的類,如果不作,系統(tǒng)將其成員默認為private,在需要時也可以自己用顯式改變。如果希望成員是公用的,使用struct比較方便,如果希望部分成員是私有的,宜用class。建議盡量使用class來建立類,寫出完全體現C+風格的程序。類的成員函數成員函數的性質類的成員函數(簡稱類函數)是函數的一種,它的用法和作用和第4章介紹過的函數基本上是一樣的,它也有返回值和函數類型,它與一般函數的區(qū)別只是: 它是屬于一個類的成員,出現在類體中。它可以被指定為private(私有的)、public(公用的)或 protected(受保護的)。在使用類函數時,要注意調用它的權限(它能否被調用)以及它的作用域(
26、函數能使用什么范圍中的數據和函數)。例如私有的成員函數只能被本類中的其他成員函數所調用,而不能被類外調用。本類中任何成員(包括私有的和在本作用域中有效的數據。成員函數可以公用的),可以一般的做法是將需要被外界調用的成員函數指定為public,它們是類的對外接口。但應注意,并非要求把所有成員函數都指定為public。有的函數并不是準備為外界調用的,而是為本類中的成員函數所調用的,就應該將它們指定為private。這種函數的作用是支持其他函數的操作,是類中其他成員的工具函數(utility function),類外用戶不能調用這些私有的工具函數。類的成員函數是類體中十分重要的部分。如果一個類中不包
27、含成員函數,就等同于C語言中的結構體了,體現不出類在面象程序設計中的作用。8.3.2 在類外定義成員函數面已經看到成員函數是在類體中定義的。也可以在類體中只寫成員函數的行函數定義。如class Student public:,而在類的外面進void display( ); private:num; string name; char sex;/公用成員函數原型/以上3行是私有數據成員void Studentdisplay( )c utnum:numendl;name:nameendl;sex:sexendl;Student stud1,stud2;/在類外定義display類函數/函數體/定義
28、兩個類對象注意: 在類體中直接定義函數時,不需要在函數名前面加上類名,因為函數屬于哪一個類是不言而喻的。但成員函數在類外定義時,必須在函數名前面加上類名,予以限定(qualifed),“”是作用域限定符(field qualifier)或稱作用域運算符,用它數是屬于哪個類的。函如果在作用域運算符“”的前面沒有類名,或者函數名前面既無類名又無作用域運算符“”,如display( )或display( )則表示display函數不屬于任何類,這個函數不是成員函數,而是全局函數,即非成員函數的一般普通函數。類函數必須先在類體中作原型,然后在類外定義,也就是說類體的位置應在函數定義之前,否則編譯時會出
29、錯。雖然函數在類的外部定義,但在調用成員函數時會根據在類中的函數原型找到函數的定義(函數代碼),從而執(zhí)行該函數。在類的對成員函數作,而在類體外定義成員函數,這是程序設計的一種良好函數,其函數體只有23行,一般可在。如果一個類時在類體中定義。多于3行的函數,一般在類體內聲明,在類外定義。8.3.3 inline 成員函數關于內置(inline)函數,已在第4章第4.5節(jié)中作過介紹。類的成員函數也可以指定為內置函數。在類體中定義的成員函數的規(guī)模一般都很小,而系統(tǒng)調用函數的過程所花費的時間開銷相對是比較大的。調用一個函數的時間開銷遠遠大于小規(guī)模函數體中全部語句的執(zhí)行時間。為了減少時間開銷,如果在類體
30、中定義的成員函數中不包括循環(huán)等控制結構,C+系統(tǒng)會自動將它們作為內置(inline)函數來處理。也就是說,在程序調用這些成員函數時,并不是真正地執(zhí)行函數的調用過程(如保留返回地址等處理),而是把函數代碼嵌入程序的調用點。這樣可以大大減少調用成員函數的時間開銷。C+要求對一般的內置函數要用關鍵字inline,但對類內定義的成員函數,可以省略inline,因為這些成員函數已被隱含地指定為內置函數。如class Studentpublic:void display( )c utnum:numendl;name:nameendl;sex:sexendl;private:num; string name
31、; char sex;其中第3行void display( )也可以寫成inline void display( )將display函數顯式地為內置函數。以上兩種寫法是等效的。對在類體內定義的函數,一般都省寫inline。應該注意的是: 如果成員函數不在類體內定義,而在類體外定義,系統(tǒng)并不把它默認為內置(inline)函數,調用這些成員函數的過程和調用一般函數的過程是相同的。如果想將這些成員函數指定為內置函數,應當用inline作顯式class Student public:。如inline void display( );/此成員函數為內置函數private:num; string name
32、; char sex;inline void Studentdisplay( )/ 在類外定義display函數為內置函數num:numendl;c utname:nameendl;sex:sexabc;可以用下面的語句來輸出該類對象所占用的字節(jié)數:c utsizeof(Time)endl;輸出的值是12。這就證明了一個對象所占的空間大小只取決于該對象中數據成員所占的空間,而與成員函數無關。函數代碼是在對象空間之外的。如果對同一個類定義了10個對象,這些對象的成員函數對應的是同一個函數代碼段,而不是10個不同的函數代碼段。需要注意的是: 雖然調用不同對象的成員函數時都是執(zhí)行同一段函數代碼,但是
33、執(zhí)行結果一般是不相同的。不同的對象使用的是同一個函數代碼段,它怎么能夠分別對不同對象中的數據進行操作呢?原來C+為此專門設立了一個名為this的指針,用來指向不同的對象。需明:(1) 不論成員函數在類內定義還是在類外定義,成員函數的代碼段都用同(2) 不要將成員函數的這種式。方式和inline(內置)函數的概念。(3) 應當說明: 常說的“某某對象的成員函數”,是從邏輯的角度而言的,而成員函數的從物理的角度而言的,二者是不方式,是的。8.4 對象成員的在程序中經常需要對象中的成員。對象中的成員可以有3種方法:通過對象名和成員運算符對象中的成員;通過指通過對象的對象中的成員;對象中的成員。象的指
34、針變量8.4.1 通過對象名和成員運算符例如在程序中可以寫出以下語句:對象中的成員stud1.num=1001;/假設num已定義為公用的整型數據成員表示將整數1001賦給對象stud1中的數據成員num。其中“.”是成員運算符,用來對成員進行限定,指明所的是哪一個對象中的成員。注意不能只寫成員名而忽略對象名。對象中成員的一般形式為對象名.成員名不僅可以在類外對象的公用數據成員,而且還可以調用對象的公用成員函數,但同樣必須象名,如對stud1.display( );display( );/正確,調用對象stud1的公用成員函數/錯誤,沒有指明是哪一個對象的display函數由于沒有指明對象名,
35、編譯時把display作為普通函數處理。應該注意所的成員是公用的(public)還是私有的(private)。只能public成員,而不能private成員,如果已定義num為私有數據成員,下面的語句是錯誤的:stud1.num=10101;/num是私有數據成員,不能被外界在類外只能調用公用的成員函數。在一個類中應當至少有一個公用的成員函數,作為對外的接口,否則就無法對對象進行任何操作。8.4.2 通過指象的指針對象中的成員在第7章第7.1.5節(jié)中介紹了指向結構體變量的指針,可以通過指針結構體中的成員。用指針訪問對象中的成員的方法與此類似。如果有以下程序段:class Timepublic:
36、hour; minute;Time t,*p; p=&t;c uthour;/數據成員是公用的/定義對象t和指針變量p/使p指象t/輸出p指向的對象中的成員hour在p指向t的前提下,p-hour,(*p).hour和t.hour三8.4.3 通過對象的變量來對象中的成員如果為一個對象定義了一個變量,它們是共占同一段單元的,實際上它們是同一個對象,只是用不同的名字表示而已。因此完全可以通過變量來如果已Time t1; Time &t2=t1;t2.hour;對象中的成員。了Time類,并有以下定義語句:/定義對象t1/定義Time類變量t2,并使之初始化為t1/輸出對象t1中的成員hour由于
37、t2與t1共占同一段因此t2.hour就是t1.hour。單元(即t2是t1的別名),本章第8.6節(jié)的例8.2中的程序(b),介紹的是作為形參的情況,讀者可以參考。變量類的封裝性和信息隱蔽公用接口與私有實現的分離從前面的介紹已知: C+通過類來實現封裝性,把數據和與這些數據有關的操作封裝在一個類中,或者說,類的作用是把數據和算法封裝在用戶抽象數據類型中。的在了一個類以后,用戶主要是通過調用公用的成員函數來實現類提供的功能(例如對數據成員設置值,顯示數據成員的值,對數據進行加工等)。因此,公用成員函數是用戶使用類的公用接口(publicerface),或者說是類的對外接口。當然并不一定要把所有成
38、員函數都指定為public(公用)的,但這時這些成員函數就不是公用接口了。在類外雖然不能直接過調用公用成員函數來私有數據成員,但可以通甚至修改私有數據成員。用戶可以調用公用成員函數來實現某些功能,而這些功能是在類時已指定的,用戶可以使用它們而不應改變它們。實際上用戶往往并不關心這些功能是如何實現的細節(jié),而只需知道調用哪個函數會得到什么結果,能實現什么功能即可。通過成員函數對數據成員進行操作稱為類的實現,為了防止用戶任意修改公用成員函數,改變對數據進行的操作,往往不讓用戶看到公用成員函數的源代碼,顯然更不能修改它,用戶只能接觸到公用成員函數的目標代碼(詳見8.5.2節(jié))??梢钥吹剑?類中作的數據
39、是私有的,實現的細節(jié)對用戶是隱蔽的,這種實現稱為私有實現(private implemenion)。這種“類的公用接口與私有實現的分離”形成了信息隱蔽。工程的一個最基本的原則就是將接口與實現分離,信息隱蔽是它的好處在于:工程中一個非常重要的概念。如果想修改或擴充類的功能,只需修改本類中有關的數據成員和與它有關的成員函數,程序中類外的部分可以不必修改。如果在編譯時發(fā)現類中的數據讀寫有錯,不必檢查整個程序,只需檢查本類中數成員函數。這些數據的少8.5.2 類在面和成員函數定義的分離象的程序開發(fā)中,一般做法是將類的(其中包含成員函數的)放在指定的頭文件中,用戶如果想用該類,只要把有關的頭文件包含進來
40、即可,不必在程序中重復書寫類的作量,節(jié)省篇幅,提高編程的效率。,以減少工由于在頭文件中包含了類的,因此在程序中就可以用該類來定義對象。由于在類體中包含了對成員函數的,在程序中就可以調用這些對象的公用成員函數。為了實現上一節(jié)所敘述的信息隱蔽,對類成員函數的定義一般不放在頭文件中,而另外放在一個文件中。例如,可以分別寫兩個文件:/student.h class Student public:void display( ); private:num;char name20; char sex;/student.cpp #include #include student.h(這是頭文件,在此文件中進行
41、類的/類)/公用成員函數原型/在此文件中進行函數的定義/不要漏寫此行,否則編譯通不過/在類外定義display類函數void Studentdisplay( )co tnum:numendl;name:nameendl;sex:sexendl;為了組成一個完整的源程序,還應當有包括主函數的源文件:/cpp主函數模塊#include #include student.hmain( )Student stud; stud.display( ); return 0;/將類頭文件包含進來/定義對象/執(zhí)行stud對象的display函數這是一個包括3個文件的程序,組成兩個文件模塊:cpp,一個是stud
42、ent.cpp。在主一個是主模塊模塊中又包含頭文件student.h。在預編譯時會將頭文件student.h中的內容取代#includestudent.h行。請注意: 由于將頭文件student.h放在用戶當前目錄中,因此在文件名兩側撇號包起來(student.h)而不用尖括號(),否則編譯時會找不到此文件。圖8.6。在運行程序時調用stud中的display函數,輸出各數據成員的值。如果一個類多次被不同的程序所選用,每次都要對包含成員函數定義的源文件(如上面的student.cpp)進行編譯,這是否可以改進呢?的確,可以不必每次都對它重復進行編譯,而只需編譯一次即可。把第一次編譯后所形成的目
43、標文件保存起來,以后在需要時把它調出來直接與程序的目標文件相連接即可。這和使用函數庫中的函數是類似的。這也是把成員函數的定義不放在頭文件中的一個好處。在實際工作中,并不是將一個類做成一個頭文件,而是將若干個常用的功能相近的類集中在類庫有兩種: 一種是C+編譯系統(tǒng)提供的標準類庫;一種是用戶根據自己的需要做成的用戶類庫,提供給自己和自己的人使用,這稱為自定義類庫。在程序開發(fā)工作中,類庫是很有用的,它可以減少用戶自己對類和成員函數進行定義的工作量。類庫包括兩個組成部分: (1)類頭文件; (2)已經過編譯的成員函數的定義,它是目標文件。用戶只需把類庫裝入到自己的計算機系統(tǒng)中(一般裝到C+編譯系統(tǒng)所在
44、的子目錄下),并在程序中用#include命令行將有關的類的頭文件包含到程序中,就可以使用這些類和其中的成員函數,順利地運行程序。這和在程序中使用C+系統(tǒng)提供的標準函數的方法是一樣的,例如用戶在調用sin函數時只需將包含聲函數的頭文件包含到程序中,即可調用該庫函數,而不必了解sin函數是怎么實現的(函數值是怎樣計算出來的)。當然,前提是系統(tǒng)已裝了標準函數庫。在用戶源文件經過編譯后,與系統(tǒng)庫(是目標文件)相連接。在用戶程序中包含類頭文件,類頭文件就成為用戶使用類的公用接口,在頭文件的類體中還提供了成員函數的函數原型,用戶只有通過頭文件才能使用有關的類。用戶看得見和接觸到的是這個頭文件,任何要使用
45、這個類的用戶只需包含這個頭文件即可。包含成員函數定義的文件就是類的實現。請?zhí)貏e注意: 類別放在兩個文本中的。和函數定義一般是分由于要求接口與實現分離,為開發(fā)商向用戶提供類庫創(chuàng)造了很好的條件。開發(fā)商把用戶所需的各種類的按類放在不同的頭文件中,同時對包含成員函數定義的源文件進行編譯,得到成員函數定義的目標代碼。商向用戶提供這些頭文件和類的實現的目標代碼(不提供函數定義的源代碼)。用戶在使用類庫中的類時,只需將有關頭文件包含到自己的程序中,并且在編譯后連接成員函數定義的目標代碼即可。由于類庫的出現,用戶可以像使用零件一樣方便地使用在實踐中積累的通用的或的類,這就大大減少了程序設計的工作量,有效地提高
46、了工作效率。8.5.3 面象程序設計中的幾個名詞類的成員函數在面象程序理論中被稱為“方法”(method),“方法”是指對數據的操作。一個“方法”對應一種操作。顯然,只有被為公用的方法(成員函數)才能被對象外界所激活。外界是通過發(fā)“消息”來激活有關方法的。所謂“消息”,其實就是一個命令,由程序語句來實現。前面的stud.display( );就是象stud發(fā)出的一個“消息”,通知它執(zhí)行其中的display“方法”(即display函數)。上面這個語句涉及3個術語: 對象、方法和消息。 stud是對象,display( )是方法,語句 “stud.display( );”是消息。8.6 類和對象
47、的簡單應用舉例例8.1 最簡單的例子。#include using namespa class Timepublic:hour; minute; sec;td;/定義Time類/數據成員為公用的main( ) Time t1; cint1.hour; cint1.minute; cint1.sec;/定義t1為Time類對象/輸入設定的時間t1.hour:t1.minute:t1.secendl; return 0;/輸出時間運行情況如下:1232 4312:32:43注意:(1) 在數據成員hour,minute,sec時記面指定對象名。(2) 不要錯寫為類名,如寫成Time.hour,Ti
48、me.minute,Time.sec是不對的。因為類是一種抽象的數據類型,并不是一個實體,也不占空間,而對象是實際存在的實體,是占空間的,其數據成員是有值的,可以被的。(3) 如果刪去主函數的3個輸入語句,即不向這些數據成員賦值,則它們的值是不可預知的。例8.2多個對象的成員。(1) 程序(a)#include using namespa class Timepublic:hour; minute; sec;main( )Time t1; cint1.hour; cint1.minute;cint1.sec;td;/定義對象t1/向t1的數據成員輸入數據c utt1.hour:t1.minut
49、e:t1.sect2.hour; cint2.minute;cint2.sec;/定義對象t2/向t2的數據成員輸入數據t2.hour:t2.minute:t2.secendl; return 0;運行情況如下:1032 4310:32:4322 32 4322:32:43/輸出t2中數據成員的值程序是清晰易懂的,但是在主函數中對不同的對象一一寫出有關操作,會使程序冗長。為了解決這個 問題,可以使用函數來進行輸入和輸出。見程序(b)。(2) 程序(b)#include using namespa class Timepublic:hour; minute; sec;td;main( )void
50、 set_time(Time&); void show_time(Time&);/函數/函數Time t1;set_time(t1); show_time(t1);/定義t1為Time類對象/調用set_time函數,向t1對象中的數據成員輸入數據/調用show_time函數,輸出t1對象中的數據Time t2; set_time(t2); show_time(t2); return 0;/定義t2為Time類對象/調用set_time函數,向t2對象中的數據成員輸入數據/調用show_time函數,輸出t2對象中的數據void set_time(Time& t)cint.hour; cint
51、.minute; cint.sec;/定義函數set_time,形參t是變量/輸入設定的時間void show_time(Time& t)/定義函數show_time,形參t是變量t.hour:t.minute:t.secendl;/輸出對象中的數據運行情況與程序(a)相同。(3) 程序(c)可以對上面的程序作一些修改,數據成員的值不再由鍵盤輸入,而在調用函數時由實參給出,并在函數中使用默認參數。將程序(b)第8行以下部分改為main( )void set_time(Time&, void show_time(Time&); Time t1; set_time(t1,12,23,34); show_time(t1);Time t2; set_time(t2); show_time(t2); return 0;minute=0,sec=0); /函數/函數/通過實參傳遞時、分、秒的值/使用默認的時、分、秒的值void set_time(Time& t,t.hour=hour; t.minute=minute; t.sec=sec;hour,sec)void show_time(Time& t)c utt.hour:t.minute:t.secendl;程序運行時的輸出為12:23:34(t1中的時、分、秒)0:0:0(t2中的時
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 水電建設招標文件內容
- 九年級歷史上冊 第二單元 近代社會的確立與動蕩 第9課 古老印度的抗爭教案 北師大版
- 2024秋七年級語文上冊 第6單元 第21課 女媧造人教案 新人教版
- 2024-2025學年高中歷史 第五單元 經濟全球化的趨勢 第27課 綜合探究:中國如何應對全球化的挑戰(zhàn)(2)教學教案 岳麓版必修2
- 2024秋四年級英語上冊 Unit 1 The Clothes We Wear Lesson 1 Skirt and Trousers教案 冀教版(三起)
- 2023三年級語文上冊 第八單元 24 司馬光說課稿 新人教版
- 高考地理一輪復習第十八章資源安全與國家安全第二節(jié)耕地資源與糧食安全課件
- 消防泵房管理制度
- 自愿贈與的合同(2篇)
- 《長城》教學課件
- 娛樂場所備案登記表樣表
- 北京版小學數學二年級上冊《探索規(guī)律》課件
- 醫(yī)務科督導檢查表格模板
- 急性顱腦損傷患者搶救流程圖
- 醫(yī)院糖尿病小組工作總結及工作計劃
- 《沐浴心育陽光 健康快樂成長》心理健康主題班會課件
- 小學生心理健康講座ppt
- GB∕T 20973-2020 膨潤土-行業(yè)標準
- 深基坑開挖危險源辨識及控制措施
- 2013工程量清單計價規(guī)范計算規(guī)則匯總
- 外國法制史英國法課件
評論
0/150
提交評論