C++程序設(shè)計課件:第4章 類與對象_第1頁
C++程序設(shè)計課件:第4章 類與對象_第2頁
C++程序設(shè)計課件:第4章 類與對象_第3頁
C++程序設(shè)計課件:第4章 類與對象_第4頁
C++程序設(shè)計課件:第4章 類與對象_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第4章 類與對象2022/9/20計算機基礎(chǔ)教研室2類與對象 本章重點 C+中的類 對象的概念 構(gòu)造函數(shù) 析構(gòu)函數(shù)2022/9/20計算機基礎(chǔ)教研室3回顧:面向過程的設(shè)計方法重點:如何實現(xiàn)細節(jié)過程,將數(shù)據(jù)與函數(shù)分開。形式:主模塊+若干個子模塊(main()+子函數(shù))。模塊是按功能來分的,所以也稱功能塊。在C+中稱為一個函數(shù),一個函數(shù)解決一個問題,即實現(xiàn)一個功能或一個操作。2022/9/20計算機基礎(chǔ)教研室4回顧:面向過程的設(shè)計方法特點:自頂向下,逐步求精功能分解。缺點:效率低,程序的可重用性差。面向過程程序設(shè)計缺點的根源在于數(shù)據(jù)與數(shù)據(jù)處理分離。2022/9/20計算機基礎(chǔ)教研室5面向?qū)ο蟮姆椒?/p>

2、使用面向?qū)ο蟮挠^點來描述模仿并處理現(xiàn)實問題。面向?qū)ο蠹夹g(shù)中的對象就是現(xiàn)實世界中某個具體的物理實體在計算機邏輯中的映射和體現(xiàn)。2022/9/20計算機基礎(chǔ)教研室6對象類計算機世界實體類別現(xiàn)實世界客觀世界抽象抽象實例化映射主觀世界對象、實體與類現(xiàn)實世界中的實體可以抽象出類別的概念。對應(yīng)于計算機世界就有一個類(class)的概念。面向?qū)ο缶褪怯嬎銠C世界模擬現(xiàn)實世界?,F(xiàn)實世界與計算機世界的映射關(guān)系2022/9/20計算機基礎(chǔ)教研室7對象對 象面向?qū)ο缶幊痰暮诵臑橛嬎銠C應(yīng)用程序提供實用基礎(chǔ)完成特定任務(wù)表示現(xiàn)實世界中的實體“對象是存在的具體實體,具有明確定義的狀態(tài)和行為。”2022/9/20計算機基礎(chǔ)教研

3、室8對象的示例收銀員對象顧客對象顧客姓名:朱麗葉年齡:28體重:52千克操作:購買商品狀態(tài)/特性姓名:布蘭尼職銜:收銀員年齡:35體重:60千克操作:收款打印帳單行為/操作“表示對象或?qū)嶓w擁有的特性稱為屬性”“對象執(zhí)行的操作稱為方法”2022/9/20計算機基礎(chǔ)教研室9類類以共同特性和操作定義實體類是用于組合各個對象所共有操作和屬性的一種機制形狀類動物類汽車類類的示例“類是具有相同屬性和行為的一組對象的集合”2022/9/20計算機基礎(chǔ)教研室10類和對象的區(qū)別 類是概念模型, 定義對象的所 有特性和所需 的操作對象是真實的模型類和對象類定義實體對象是實際的實體類是對象的原型所有屬于同一個類的對

4、象都具有相同的特性和操作2022/9/20計算機基礎(chǔ)教研室11封裝信息隱藏,隱藏對象的實現(xiàn)細節(jié)將東西包裝在一起,然后以新的完整形式呈現(xiàn)出來例如,兩種或多種化學藥品組成一個膠囊將方法和屬性一起包裝到一個單元中,單元以類的形式實現(xiàn)“隱藏屬性、方法或?qū)崿F(xiàn)細節(jié)的過程稱為封裝?!?022/9/20計算機基礎(chǔ)教研室12繼承與派生是支持層次分類的一種機制,在保持原有類特性的基礎(chǔ)上,進行更具體的說明。2022/9/20計算機基礎(chǔ)教研室13多態(tài)性語文、數(shù)學、英語、政治、物理、化學、生物高中生計 算平均成績大學生高數(shù)、英語、計算機、線性代數(shù)多態(tài):同一名稱,不同的功能實現(xiàn)方式。目的:達到行為標識統(tǒng)一,減少程序中標識

5、符的個數(shù)。2022/9/20計算機基礎(chǔ)教研室14結(jié)構(gòu)化程序與面向?qū)ο蟪绦虻谋容^問題:輸入圓的半徑,求圓的周長和面積數(shù)據(jù)描述:半徑,周長,面積均用實型數(shù)表示數(shù)據(jù)處理:輸入半徑 r;計算周長 = 2*r ;計算面積 = * r2 ;輸出半徑,周長,面積; 2022/9/20計算機基礎(chǔ)教研室15方法一:用結(jié)構(gòu)化方法編程,求圓的周長和面積#includeusing namespace std;void main () double r, girth, area ; const double PI = 3.1415 ; cout r ; girth = 2 * PI * r ; area = PI *

6、r * r ; cout radius = r endl ; cout girth = girth endl ; cout area = area endl ;2022/9/20計算機基礎(chǔ)教研室16方法二:用面向?qū)ο蠓椒ň幊?,求圓的周長和面積 實例化分析“圓”是抽象的類類型建立具體的圓(對象)半徑?圓的周長 ? 面積 ?2022/9/20計算機基礎(chǔ)教研室17方法二:用面向?qū)ο蠓椒ň幊?,求圓的周長和面積 圓類 屬性 半徑 方法 置半徑值取半徑值求周長 求面積實例化分析2022/9/20計算機基礎(chǔ)教研室18方法二:用面向?qū)ο蠓椒ň幊?,求圓的周長和面積#includeusing namespace

7、std;class Circle double radius ;public : void Set_Radius( double r ) radius = r ; double Get_Radius() return radius ; double Get_Girth() return 2 * 3.14 * radius ; double Get_Area() return 3.14 * radius * radius ; ;void main() Circle A, B ; A.Set_Radius( 6.23 ) ; cout A.Radius = A.Get_Radius() endl

8、; cout A.Girth = A.Get_Girth() endl ; cout A.Area = A.Get_Area() endl ; B.Set_Radius( 10.5 ) ; cout B.radius = B.Get_Radius() endl ; cout B.Girth= B.Get_Girth() endl ; cout B.Area = B.Get_Area() endl ; 定義Circle類數(shù)據(jù)成員成員函數(shù)建立對象(類類型的變量)通過對象調(diào)用類的成員函數(shù)2022/9/20計算機基礎(chǔ)教研室19類與對象的基本概念 4.1.3 對象的創(chuàng)建與使用 4.1.1 C+類的定義

9、4.1.2 成員函數(shù)的定義 20 類是一種數(shù)據(jù)類型。描述客觀事物必須用不同的數(shù)據(jù)類型來描述不同的方面。 4.1.1 C+類的定義 class CGoodsprivate : char Name21;/商品名稱 int Amount;/商品數(shù)量 float Price;/商品單價 float Total_value;/商品總價public : void RegisterGoods(char, int, float); /輸入數(shù)據(jù) void CountTotal( ); /計算商品總價值 void GetName(char); /讀取商品名 int GetAmount( ); /讀取商品數(shù)量 fl

10、oat GetPrice( ); /讀取商品單價 float GetTotal_value( ); /讀取商品總價值 ; class CGoods稱為類頭,關(guān)鍵字class是數(shù)據(jù)類型說明符,指出下面說明的是類;標識符CGoods是商品這個類的類型名最后的分號;不可少,表示是一條說明語句private和public是訪問限定符花括號 中的部分稱為類體,類體中定義了類成員表,包含數(shù)據(jù)成員和成員函數(shù)2022/9/20計算機基礎(chǔ)教研室21訪問限定符(access specifier):public(公共的)說明的成員能從外部進行訪問。private(私有的)和protected(保護的)說明的成員不能

11、從外部進行訪問。 每種說明符可在類體中使用多次。 訪問限定符的作用域是從該說明符出現(xiàn)開始到下一個說明符之前或類體結(jié)束之前結(jié)束。 如果在類體起始點無訪問說明符,系統(tǒng)默認定義為私有(private)。 訪問限定符private(私有的)和protected(保護的)體現(xiàn)了類具有封裝性。4.1.1 C+類的定義 2022/9/20計算機基礎(chǔ)教研室22封裝: 類把數(shù)據(jù)(事物的屬性)和函數(shù)(事物的行為操作)封裝為一個整體。 接口: 通常數(shù)據(jù)成員被說明成私有的,函數(shù)成員被說明成公有的;從外部對數(shù)據(jù)成員進行操作,只能通過公有函數(shù)來完成,數(shù)據(jù)受到了良好的保護,不易受副作用的影響。公有函數(shù)集定義了類的接口(in

12、terface)。 成員函數(shù)可以直接使用類定義中的任一成員,可以處理數(shù)據(jù)成員,也可調(diào)用函數(shù)成員。注意: 類是一種數(shù)據(jù)類型,定義時系統(tǒng)不為類分配存儲空間,所以不能對類的數(shù)據(jù)成員初始化。類中的任何數(shù)據(jù)成員也不能使用關(guān)鍵字extern、auto或register限定其存儲類型。 2022/9/20計算機基礎(chǔ)教研室234.1.2 成員函數(shù)的定義 通常在類定義中,成員函數(shù)僅作聲明。函數(shù)定義通常在類的說明之后進行,其格式如下:返回值類型 類名:函數(shù)名(參數(shù)表) /函數(shù)體 運算符“:”稱為作用域解析運算符(scope resolution operator),它指出該函數(shù)是屬于其左操作數(shù)對應(yīng)的類的成員函數(shù)。

13、24類CGoods成員函數(shù)的定義void CGoods:RegisterGoods(char name , int amount , float price) strcpy(Name , name) ; /字符串復(fù)制函數(shù) Amount = amount ; Price = price ;void CGoods:CountTotal(void) Total_value = Price*Amount;void CGoods:GetName(char name) strcpy(name , Name);int CGoods:GetAmount(void) return(Amount) ;float

14、CGoods:GetPrice(void) return(Price) ;float CGoods:GetTotal_value(void) return(Total_value) ;2022/9/20計算機基礎(chǔ)教研室25定義對象: 對象是類的實例(instance)。定義一種數(shù)據(jù)類型只是告訴編譯系統(tǒng)該數(shù)據(jù)類型的構(gòu)造,并沒有預(yù)定內(nèi)存。類只是一個樣板,以此樣板可以在內(nèi)存中開辟出同樣結(jié)構(gòu)的實例對象。格式如下:CGoods Car; 這個定義創(chuàng)建了CGoods類的一個對象Car,同時為它分配了屬于它自己的存儲塊,用來存放數(shù)據(jù)和對這些數(shù)據(jù)實施操作的成員函數(shù)(代碼)。對象只在定義它的域中有效。4.1.3

15、 對象的創(chuàng)建與使用 2022/9/20計算機基礎(chǔ)教研室26數(shù)據(jù)區(qū)對象1數(shù)據(jù)區(qū)對象數(shù)據(jù)區(qū)對象公共代碼區(qū) 系統(tǒng)為每個對象分配一個數(shù)據(jù)區(qū),公共代碼區(qū)(放成員函數(shù)的區(qū)域)為各對象共用。 注意: 區(qū)別同一個類的各個不同對象是由數(shù)據(jù)成員決定的;操作的代碼對所有對象都是一樣的。 通過sizeof計算對象占用的存儲空間時不包括函數(shù)代碼所占用的存儲空間。 對象的存儲2022/9/20計算機基礎(chǔ)教研室27#includeusing namespace std;class Circle double radius ;public : void Set_Radius( double r ) ; double Get_

16、Radius() ; double Get_Girth() ; double Get_Area() ; ;Circle 類定義數(shù)據(jù)成員聲明成員函數(shù)聲明回顧 用面向?qū)ο蠓椒ň幊?,求圓的周長和面積 2022/9/20計算機基礎(chǔ)教研室28void Circle:Set_Radius(double r) radius = r; double Circle:Get_Radius() return radius; double Circle:Get_Girth() return 2 * 3.14f * radius; double Circle:Get_Area() return 3.14f * radi

17、us * radius; 回顧 用面向?qū)ο蠓椒ň幊?,求圓的周長和面積 成員函數(shù)實現(xiàn)2022/9/20計算機基礎(chǔ)教研室29void main() Circle A, B; A.Set_Radius(6.23) ; coutA.Radius = A.Get_Radius()endl ; coutA.Girth = A.Get_Girth()endl ; cout A.Area = A.Get_Area()endl ; B.Set_Radius( 10.5 ) ; coutB.radius = B.Get_Radius()endl ; coutB.Girth=B.Get_Girth()endl ;

18、coutB.Area = B.Get_Area()endl ; 建立對象(類類型變量)通過對象調(diào)用類的成員函數(shù)回顧 用面向?qū)ο蠓椒ň幊?,求圓的周長和面積 2022/9/20計算機基礎(chǔ)教研室30內(nèi)聯(lián)函數(shù): 在類定義外部定義的成員函數(shù)之前可以使用inline關(guān)鍵字說明其為內(nèi)聯(lián)函數(shù);在類定義中定義的成員函數(shù)則可以省略inline,系統(tǒng)將自動是其為內(nèi)聯(lián)函數(shù)。 如Get_Area()函數(shù)可定義為:inline double Circle:Get_Area() return 3.14f * radius * radius; 注意:inline只是一個建議,最后由編譯器決定是否執(zhí)行。對象的存儲方式是物理的,

19、這是由計算機來完成的,它并不影響類在邏輯上的封裝性。2022/9/20計算機基礎(chǔ)教研室31數(shù)據(jù)成員多為私有的,要對它們進行初始化,必須用一個公有函數(shù)來進行。同時這個函數(shù)應(yīng)該在且僅在定義對象時自動執(zhí)行一次。稱為:構(gòu)造函數(shù)(constructor)4.3.1構(gòu)造函數(shù)的定義與使用 4.3.2析構(gòu)函數(shù)的定義與使用4.3 構(gòu)造函數(shù)與析構(gòu)函數(shù) 2022/9/20計算機基礎(chǔ)教研室32由于類的封裝性,類的對象不能象普通變量一樣初始化。構(gòu)造函數(shù)的作用是在對象被創(chuàng)建時使用特定的值構(gòu)造對象,或者說將對象初始化為一個特定的狀態(tài)。在對象創(chuàng)建時由系統(tǒng)自動調(diào)用。如果程序中未聲明,則系統(tǒng)自動產(chǎn)生出一個默認形式的構(gòu)造函數(shù)。構(gòu)造

20、函數(shù)允許為內(nèi)聯(lián)函數(shù)、重載函數(shù)、帶默認參數(shù)值的函數(shù)。4.3.1 構(gòu)造函數(shù)的定義與使用2022/9/20計算機基礎(chǔ)教研室33函數(shù)名與類名相同。構(gòu)造函數(shù)無函數(shù)返回類型說明。注意是什么也不寫,也不可寫void。構(gòu)造函數(shù)可以在類中定義,也可以在類外定義。構(gòu)造函數(shù)可以重載,系統(tǒng)在自動調(diào)用時按一般函數(shù)重載的規(guī)則選一個執(zhí)行。構(gòu)造函數(shù)的特征CGoods:CGoods() Name0 = 0; Price = 0; Account = 0; Total_value = 0;CGoods:CGoods(char name) strcpy(Name, name); Price = 0; Account = 0; To

21、tal_value = 0; 2022/9/20計算機基礎(chǔ)教研室34如果類定義中沒有給出構(gòu)造函數(shù),則編譯器自動給出一個默認的構(gòu)造函數(shù): 類名( ) 但只要定義了一個構(gòu)造函數(shù),系統(tǒng)就不會自動生成默認的構(gòu)造函數(shù)。如果定義的構(gòu)造函數(shù)是無參的或各參數(shù)均有默認值的,編譯器會認為其是默認的構(gòu)造函數(shù),默認的構(gòu)造函數(shù)只能有一個 。建立新對象時,該對象所屬的類的構(gòu)造函數(shù)自動被調(diào)用,并且在其生命期中只調(diào)用一次。構(gòu)造函數(shù)的特征2022/9/2035#include using namespace std;class Q int x, y;public: Q(int a, int b) cout構(gòu)造函數(shù)Q(a, b)

22、endl; x=a; y=b; Q(int a) cout構(gòu)造函數(shù)Q(a)endl; x=a; y=0; void P(void) coutxtyendl; ;void main(void) Q q1(50,100); q1.P(); Q q2(50); q2.P();輸出:構(gòu)造函數(shù)Q(a,b)50100構(gòu)造函數(shù)Q(a)500構(gòu)造函數(shù)舉例 2022/9/20計算機基礎(chǔ)教研室36析構(gòu)函數(shù)特征: 當一個對象的生命周期結(jié)束時,C+會自動調(diào)用析構(gòu)函數(shù)對該對象并進行善后工作。1.構(gòu)函數(shù)名與類名相同,但在前面加上字符 ,如:CGoods()2.析構(gòu)函數(shù)無函數(shù)返回類型,與構(gòu)造函數(shù)在這方面是一樣的,但析構(gòu)函數(shù)

23、不帶任何參數(shù)。3. 一個類只能有一個析構(gòu)函數(shù),這與構(gòu)造函數(shù)不同。類定義中沒有給出析構(gòu)函數(shù)時,編譯器也自動給出一個默認的析構(gòu)函數(shù)。4. 對象注銷時,系統(tǒng)自動調(diào)用析構(gòu)函數(shù)。4.3.2 析構(gòu)函數(shù)的定義與使用2022/9/2037#include using namespace std;class Q int x, y;public: Q(int a, int b) cout構(gòu)造函數(shù)Q(a, b)endl; x=a; y=b; Q() cout析構(gòu)函數(shù)Q()endl; void P(void) coutxtyendl; ;void main(void) Q q1(50,100); q1.P(); co

24、ut退出主函數(shù)!n;輸出:構(gòu)造函數(shù)Q(a,b)50100退出主函數(shù)!析構(gòu)函數(shù)Q()析構(gòu)函數(shù)舉例 2022/9/20計算機基礎(chǔ)教研室38一圓型游泳池如圖所示,現(xiàn)在需在其周圍建一圓型過道,并在其四周圍上柵欄。柵欄價格為35元/米,過道造價為20元/平方米。過道寬度為3米,游泳池半徑由鍵盤輸入。要求編程計算并輸出過道和柵欄的造價。游泳池過道類的應(yīng)用舉例2022/9/20計算機基礎(chǔ)教研室39#include using namespace std;const float PI = 3.14159;const float FencePrice = 35;const float ConcretePrice

25、 = 20;/聲明類Circle及其數(shù)據(jù)和方法class Circle private: float radius; public: Circle(float r); /構(gòu)造函數(shù) float Circumference(); /圓周長 float Area() ; /圓面積;Circle:Circle(float r) /構(gòu)造函數(shù)初始化數(shù)據(jù)成員radius radius = r; float Circle:Circumference() /計算圓的周長 return 2 * PI * radius; float Circle:Area() /計算圓的面積 return PI * radius

26、* radius;2022/9/20計算機基礎(chǔ)教研室40void main() float radius; float FenceCost, ConcreteCost; /提示用戶輸入半徑 coutradius; /聲明 Circle 對象 Circle Pool(radius); Circle PoolRim(radius + 3); /計算柵欄造價并輸出 FenceCost = PoolRim.Circumference() * FencePrice; coutFencing Cost is ¥FenceCostendl; /計算過道造價并輸出 ConcreteCost = (PoolRi

27、m.Area() - Pool.Area()*ConcretePrice; coutConcrete Cost is ¥ConcreteCostendl;運行結(jié)果:Enter the radius of the pool: 10Fencing Cost is ¥2858.85Concrete Cost is ¥4335.392022/9/20計算機基礎(chǔ)教研室414.4.1 引用 4.4.2 復(fù)制構(gòu)造函數(shù) 4.4.3 成員對象與構(gòu)造函數(shù) 4.4 引用與復(fù)制構(gòu)造函數(shù)2022/9/20計算機基礎(chǔ)教研室42引用的導(dǎo)入: 傳值方式的參數(shù)傳遞是在函數(shù)域中為形參分配內(nèi)存,而把實參的數(shù)值傳遞到新分配的內(nèi)存中。

28、它的優(yōu)點是實現(xiàn)實參與形參隔離,有效避免函數(shù)的副作用。 問題:如果要求改變實參的值,怎么辦?如果實參是一個復(fù)雜的對象,重新分配內(nèi)存會引起程序執(zhí)行效率大大下降,怎么辦? 有一種導(dǎo)出型數(shù)據(jù)類型引用(reference)可以解決上面的難題。引用又稱別名(alias)。引用2022/9/20計算機基礎(chǔ)教研室43引用&在這里是引用的說明符 引用是給一個已經(jīng)定義的變量重新起一個別名,而不是定義一個新的變量,定義的格式為:類型 &引用類型變量名 = 已定義過的變量名;例如:double number;double &newnum = number;注意: newnum是變量number的別名,C+系統(tǒng)不為引用

29、類型變量分配內(nèi)存空間 。 在程序中修改了newnum也就是修改了number,兩位一體。 引用主要用于函數(shù)之間的數(shù)據(jù)傳遞。44【例4.3】引用作為形參 Xyd1d2temp1.4142.7181.4142.7181.414參數(shù)d1、d2為引用時內(nèi)存分配示意 void swap(double & d1, double & d2) double temp ; temp=d1 ; d1=d2 ; d2=temp ; int main(void) double x , y ; cout請輸入x和y的值 xy ; swap(x,y) ; coutx=xt y=yn; return 0; 45 同一個類的

30、對象在內(nèi)存中有完全相同的結(jié)構(gòu),如果作為一個整體進行復(fù)制是完全可行的。這個復(fù)制過程只需要復(fù)制數(shù)據(jù)成員,而成員函數(shù)是共用的。 在建立對象時可用同一類的另一個對象來初始化該對象,這時所用的構(gòu)造函數(shù)稱為復(fù)制構(gòu)造函數(shù)。復(fù)制構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù)的特征:1. 復(fù)制構(gòu)造函數(shù)的參數(shù)必須采用引用。2.系統(tǒng)會自動提供稱為默認的按成員語義支持的復(fù)制構(gòu)造函數(shù),亦稱為默認的按成員初始化。按成員作復(fù)制是通過依次復(fù)制每個數(shù)據(jù)成員實現(xiàn)的。3.同類對象之間可以用賦值運算符 = 直接復(fù)制。2022/9/20計算機基礎(chǔ)教研室46CGoods:CGoods(CGoods &cgd) strcpy(Name, cgd.Name); Pr

31、ice = cgd.Price; Amount = cgd.Amount; Total_value = cgd.Total_valueCGood Car1(夏利2000,30,98000.00);/調(diào)用三個參數(shù)的構(gòu)造函數(shù)CGood Car2 = Car1; /調(diào)用復(fù)制構(gòu)造函數(shù)CGood Car3 (Car1); /調(diào)用復(fù)制構(gòu)造函數(shù),Car1為實參這樣三個對象的初始化結(jié)果完全一樣。復(fù)制構(gòu)造函數(shù) 當成員函數(shù)的參數(shù)為同一類(class)的對象或它的引用,在函數(shù)體內(nèi)使用參數(shù)對象的私有數(shù)據(jù)成員時,可用對象名加成員訪問操作符點號進行。 從邏輯上講,每個對象有自己的成員函數(shù),訪問同類其他對象的私有數(shù)據(jù)成員應(yīng)

32、通過該對象的公有函數(shù),不能直接訪問。但在物理上只有一個成員函數(shù)代碼,所以直接訪問是合理的。僅在成員函數(shù)中可以這樣做。2022/9/20計算機基礎(chǔ)教研室47class Pointpublic: Point(int xx=0, int yy=0)X=xx; Y=yy; Point(Point& p); int GetX() return X; int GetY() return Y;private: int X, Y;Point:Point (Point &p) X = p.X; Y = p.Y; cout復(fù)制構(gòu)造函數(shù)被調(diào)用endl;復(fù)制構(gòu)造函數(shù)舉例2022/9/20計算機基礎(chǔ)教研室48(1)當用

33、類的一個對象去初始化該類的另一個對象時系統(tǒng)自動調(diào)用復(fù)制構(gòu)造函數(shù)實現(xiàn)拷貝賦值。void main(void) Point A(1, 2); Point B(A); /復(fù)制構(gòu)造函數(shù)被調(diào)用 coutB.GetX()endl;復(fù)制構(gòu)造函數(shù)調(diào)用的三種情況2022/9/20計算機基礎(chǔ)教研室49(2)若函數(shù)的形參為類對象,調(diào)用函數(shù)時,實參賦值給形參,系統(tǒng)自動調(diào)用復(fù)制構(gòu)造函數(shù)。 void fun1(Point p) coutp.GetX()endl; void main() Point A(1, 2); fun1(A); /調(diào)用復(fù)制構(gòu)造函數(shù) 復(fù)制構(gòu)造函數(shù)調(diào)用的三種情況2022/9/20計算機基礎(chǔ)教研室50(3

34、)當函數(shù)的返回值是類對象時,系統(tǒng)自動調(diào)用復(fù)制構(gòu)造函數(shù)。Point fun2() Point A(1, 2); return A; /調(diào)用復(fù)制構(gòu)造函數(shù)void main() Point B; B = fun2(); 復(fù)制構(gòu)造函數(shù)調(diào)用的三種情況2022/9/20計算機基礎(chǔ)教研室51聚合(aggregation): 類中的成員,除了數(shù)據(jù)成員和成員函數(shù)外,還有成員對象,即用其他類的對象作為類的成員。使用成員對象的技術(shù)稱為聚合。成員對象是實體,系統(tǒng)不僅為它分配內(nèi)存,而且要進行初始化。成員對象與構(gòu)造函數(shù)2022/9/20計算機基礎(chǔ)教研室52定義形式:類名:類名(參數(shù)表) : 對象1(參數(shù)), 對象2(參數(shù)

35、), . 本類初始化 其中,參數(shù)表可以包含成員對象和數(shù)據(jù)成員初始化所需的形參。 冒號以后部分稱為初始化區(qū),是函數(shù)體的一部分,在構(gòu)造函數(shù)的聲明中不應(yīng)被包含。 初始化區(qū)主要用于完成成員對象的初始化,也可以在該處對數(shù)據(jù)成員進行初始化。含成員對象的構(gòu)造函數(shù)2022/9/20計算機基礎(chǔ)教研室53class Pointprivate: float x,y; /點的坐標public: Point(float xx, float yy); /構(gòu)造函數(shù) float GetX(void) return x; /取X坐標 float GetY(void) return y;/取Y坐標;類聚合構(gòu)造函數(shù)實例class

36、Lineprivate: Point p1, p2; /線段的兩個端點 double s; /線段的長度public: Line(Point a, Point b); /構(gòu)造函數(shù)聲明,無初始化區(qū);2022/9/20計算機基礎(chǔ)教研室54Line:Line(Point a, Point b):p1(a), p2(b) double x = double(p1.GetX() - p2.GetX(); double y = double(p1.GetY() - p2.GetY(); s = sqrt(x*x+y*y); 類聚合構(gòu)造函數(shù)實例Line:Line(Point a, Point b):p1(a

37、), p2(b), s(0)2022/9/20計算機基礎(chǔ)教研室55 含對象成員的析構(gòu)函數(shù): 因為析構(gòu)函數(shù)沒有參數(shù),所以包含成員對象的類的析構(gòu)函數(shù)形式上并無特殊之處。但是撤銷該類對象時,會首先調(diào)用自己的析構(gòu)函數(shù),再調(diào)用成員對象的析構(gòu)函數(shù),調(diào)用次序與初始化時的次序相反。成員對象與構(gòu)造函數(shù)2022/9/20計算機基礎(chǔ)教研室56【例4.6】含有成員對象的類的構(gòu)造函數(shù)#include using namespace std;class StudentID long value;public: StudentID(long id=0) value=id; cout賦給學生的學號:valueendl; St

38、udentID() cout刪除學號:valueendl; ;2022/9/20計算機基礎(chǔ)教研室57class Studentprivate: StudentID id; char name20;public: Student (char sname=no name, long sid=0):id(sid) strcpy(name, sname); cout學生名:nameendl; Student() cout刪除學生名:nameendl; ;int main() Student ss(朱明, 82020132); return 0;運行結(jié)果為:賦給學生的學號: 82020132學生名:朱明

39、刪除學生名:朱明刪除學號: 820201322022/9/20計算機基礎(chǔ)教研室58構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序:1. 對全局定義的對象,當程序進入入口函數(shù)main之前對象就已經(jīng)定義,整個程序結(jié)束時調(diào)用析構(gòu)函數(shù)。2. 對于局部定義的對象,每當程序控制流到達該對象定義處時,調(diào)用構(gòu)造函數(shù)。當程序控制走出該局部域時,則調(diào)用析構(gòu)函數(shù)。3. 對于靜態(tài)局部定義的對象,在程序控制首次到達該對象定義處時,調(diào)用構(gòu)造函數(shù)。當整個程序結(jié)束時調(diào)用析構(gòu)函數(shù)。成員對象與構(gòu)造函數(shù)2022/9/20計算機基礎(chǔ)教研室59【例4.7】演示對象創(chuàng)建和撤消的對應(yīng)關(guān)系#include using namespace std;class

40、complexprivate: double real, image; public: complex() /默認的構(gòu)造函數(shù) real=0.0;image=0.0; coutInitializing 0 0endl; complex(double r,double i=0.0) /帶參數(shù)的構(gòu)造函數(shù) real=r;image=i; coutInitializingrtiendl; complex(complex &com); /復(fù)制的構(gòu)造函數(shù)聲明 complex()cout Destructorendl; void assign(complex com) real=com.real; image

41、=com.image; void print() coutreal+imageiendl; ;2022/9/20計算機基礎(chǔ)教研室60inline complex:complex(complex &com)/復(fù)制構(gòu)造函數(shù)的定義 coutCopycom.realtcom.imageendl; real=com.real; image=com.image;complex global; /全局對象首先建立complex fun(complex com) coutEntering functionendl; global.assign(com); coutExiting functionendl; r

42、eturn global; int main() cout Entering main endl; complex com1, com2(5.6, 7.5); complex com3 = com1; com3.print(); global.print(); com1=fun(com2); com1.print(); coutExiting mainendl; return 0;2022/9/20計算機基礎(chǔ)教研室61運行結(jié)果:Initializing 0 0 /全局對象global建立,調(diào)默認的構(gòu)造函數(shù)Entering main /進入入口函數(shù)mainInitializing 0 0 /用默

43、認的構(gòu)造函數(shù)建立com1Initializing 5.6 7.5 /用帶參數(shù)的構(gòu)造函數(shù)建立com2Copy 0 0 /用復(fù)制的構(gòu)造函數(shù)建立com30+0i /打印com30+0i /打印globalCopy 5.6 7.5 /調(diào)用全局函數(shù)fun(),調(diào)用復(fù)制構(gòu)造函數(shù)建立 /局部對象,fun()中的形參comEntering function /進入全局函數(shù)fun()Copy 5.6 7.5 /進入global.assign(),調(diào)用復(fù)制構(gòu)造函數(shù) /建立局部對象,assign()中的形參com2022/9/20計算機基礎(chǔ)教研室62Destructor /退出global.assign(),調(diào)用析

44、構(gòu)函數(shù), /清assign()中的形參comExiting function /將退出fun()Copy 5.6 7.5 /返回對象時調(diào)用復(fù)制構(gòu)造函數(shù)建立臨時對象Destructor /退出fun(),調(diào)用析構(gòu)函數(shù),清fun()的comDestructor /返回的臨時對象賦給com1后析構(gòu)5.6 + 7.5i /打印com1Exit main /將退出入口函數(shù)mainDestructor/退出入口函數(shù)前,調(diào)用析構(gòu)函數(shù),清com3Destructor/退出入口函數(shù)前,調(diào)用析構(gòu)函數(shù),清com2Destructor/退出入口函數(shù)前,調(diào)用析構(gòu)函數(shù),清com1Destructor/退出入口函數(shù)前,調(diào)用

45、析構(gòu)函數(shù),清global本例運行結(jié)果應(yīng)與程序?qū)Ρ?,看看程序運行的細節(jié)。2022/9/20計算機基礎(chǔ)教研室63運算符重載的概念:運算符的重載是特殊的函數(shù)重載,必須定義一個函數(shù),并通知C+編譯器,當遇到該重載的運算符時調(diào)用此函數(shù)。這個函數(shù)叫做運算符重載函數(shù),通常為類的成員函數(shù)。 一個運算符被重載后,原有意義沒有失去,只是定義了相對某個特定類的一個新運算符。 4.5 運算符的重載2022/9/20計算機基礎(chǔ)教研室64可以重載C+中除下列運算符外的所有運算符:. .* : ?:只能重載C+語言中已有的運算符,不可臆造新的。不改變原運算符的優(yōu)先級和結(jié)合性。不能改變操作數(shù)個數(shù)。經(jīng)重載的運算符,其操作數(shù)中至

46、少應(yīng)該有一個是自定義類型。運算符重載的規(guī)則和限制2022/9/20計算機基礎(chǔ)教研室65重載為成員函數(shù),解釋為:ObjectL.operator+ (ObjectR) 左操作數(shù)由ObjectL通過this指針傳遞,右操作數(shù)由參數(shù)ObjectR傳遞 ObjectL + ObjectR 二元運算符+ 語法形式為:類型 類名 : operator op(參數(shù)表) /相對于該類定義的操作 operator是關(guān)鍵字,它與重載的運算符op一起構(gòu)成函數(shù)名。2022/9/20計算機基礎(chǔ)教研室66class Complex double Real, Image ;public: Complex(double r=

47、0.0, double i=0.0):Real(r),Image(i) Complex(Complex &com)Real=com.Real; Image=com.Image; void Print() coutReal=RealtImage=Imagen; Complex operator+(Complex); /重載+運算符函數(shù) Complex operator+(double); /重載+運算符函數(shù) Complex operator=(Complex); /重載=運算符函數(shù); Complex Complex:operator+(Complex c)/重載+ Complex Temp(Re

48、al+c.Real , Image+c.Image) ; return Temp; 【例4.8】復(fù)數(shù)類,應(yīng)用它進行復(fù)數(shù)運算2022/9/20計算機基礎(chǔ)教研室67Complex Complex:operator+(double d) /重載+ return Complex(Real+d , Image); Complex Complex:operator=(Complex c)/重載= Complex temp; /定義temp為可返回Complex類型值,使=可連續(xù)使用 temp.Real=c.Real; temp.Image=c.Image; Real=temp.Real; Image=te

49、mp.Image; return temp;int main(void) Complex c1(1.0,1.0), c2(2.0,2.0), c3(4.0,4.0), c; double d=0.5; c1.Print(); c=c2+c3; c.Print(); c=c+d; c.Print(); /可用0.5代替d c=c3=c2=c1; c.Print(); /連續(xù)賦值 return 0; 在return后面跟的表達式中調(diào)用的是類的構(gòu)造函數(shù),它為新建的作為返回值載體的無名對象進行初始化。 2022/9/20計算機基礎(chǔ)教研室68運算符的重載引用作為參數(shù): Complex Complex:o

50、perator+(const Complex &c) return Complex(real+c.real, Image+c.Image) ; 注意:參數(shù)采用對象的引用而不是對象本身,調(diào)用時不再重新分配內(nèi)存建立一個復(fù)制的對象,函數(shù)效率會更高。而在引用形式參數(shù)類型說明前加const關(guān)鍵字,表示被引用的實參是不可改變的,如程序員不當心在函數(shù)體中重新賦值了被引用的實參, C+編譯器會認為出錯。2022/9/20計算機基礎(chǔ)教研室692.當用類的成員函數(shù)實現(xiàn)運算符的重載時,運算符重載函數(shù)的參數(shù)(當為雙目運算符時)為一個或(當為單目運算符時)沒有。運算符的左操作數(shù)一定是對象,因為重載的運算符是該對象的成員

51、函數(shù),而右操作數(shù)是該函數(shù)的參數(shù)。 3.單目運算符“+”和“-”存在前置與后置問題。前置“+”格式為: 返回類型 類名:operator+() 而后置“+”格式為: 返回類型 類名:operator+(int) 后置“+”中的參數(shù)int僅用作區(qū)分。小結(jié):1. 運算符重載函數(shù)的函數(shù)名必須為關(guān)鍵字operator加一個合法的運算符。C+中只有極少數(shù)的運算符不允許重載。 運算符的重載2022/9/20計算機基礎(chǔ)教研室70運算符的重載問題:例5.7中:c = c + d;語句,改為c = d + c;因為d不是Complex的對象,C+編譯器將無法找到合適的重載的“+”運算符對應(yīng)的函數(shù),最終給出出錯信息

52、。怎樣解決? 2022/9/20計算機基礎(chǔ)教研室71通過聲明為模塊B的友元,模塊A能夠直接引用到模塊B中被隱藏的信息。友元破壞了數(shù)據(jù)封裝和數(shù)據(jù)隱藏的機制,應(yīng)盡量不使用或少使用友元??梢允褂糜言瘮?shù)和友元類。友元函數(shù)是在類聲明中由關(guān)鍵字friend修飾說明的非成員函數(shù),在它的函數(shù)體中能夠通過對象名直接訪問private和protected成員。4.6 友元2022/9/20計算機基礎(chǔ)教研室72 重載為友員函數(shù),解釋為:operator+ (ObjectL, ObjectR) 左右操作數(shù)都由參數(shù)傳遞 二元運算符ObjectL + ObjectR2022/9/20計算機基礎(chǔ)教研室73class Co

53、mplex friend Complex operator + (double,Complex); /opration+說明為類Complex類的友元函數(shù)Complex operator + (double d , Complex c) return Complex(d + c.Real , c.Image) ; /friend只用于類說明中,定義時不加friend/注意友元不是成員函數(shù),但可以直接訪問私有成員int main(void) ; c=d+c1; c.print(); return 0;解釋:d+c1被C+編譯器解釋為:operator+(d, c1)友元 2022/9/20計算機

54、基礎(chǔ)教研室74例4.8_1】 用友元函數(shù)重載運算符class Complex doubleReal, Image ;public : Complex(double r=0.0, double i=0.0) : Real(r), Image(i) Complex(Complex &com) Real = com.Real; Image=com.Image; void Print() coutReal=RealtImage=Imagen friend Complex operator+(const Complex &,const Complex &); friend Complex &operat

55、or +=(Complex &,const Complex &); ;2022/9/20計算機基礎(chǔ)教研室75Complex &operator +=(Complex &c1,const Complex &c2) /重載復(fù)數(shù)+= c1.Real = c1.Real + c2.Real; c1.Image = c1.Image + c2.Image; return c1; /返回由引用參數(shù)傳遞過來的變量,函數(shù)返回值可為引用Complex operator+(const Complex &c1,const Complex &c2) return Complex(c1.Real + c2.Real,

56、c1.Image + c2.Image); /隱式說明局部對象int main(void) Complex c1(1.0,1.0) , c2(2.0,2.0) , c3(4.0,4.0) , c; double d=0.5 ; c1.Print(); c=c2+c3; c.Print(); /兩復(fù)數(shù)相加 c+=c2+=c1; c.Print(); /連續(xù)加賦值 c=c+d; c.Print(); /復(fù)數(shù)加實數(shù) c=d+c; c.Print(); /實數(shù)加復(fù)數(shù) return 0;2022/9/20計算機基礎(chǔ)教研室76友元函數(shù)注意點: 1.友元函數(shù)不是類的成員函數(shù),在函數(shù)體中訪問對象的成員,必須用

57、對象名加運算符.加對象成員名。 2.友元函數(shù)不受類中的訪問權(quán)限關(guān)鍵字限制,可以把它放在類的公有、私有、保護部分,結(jié)果一樣。 3.某類的友元函數(shù)的作用域并非該類域。如果該友元函數(shù)是另一類的成員函數(shù),則其作用域為另一類的類域,否則與一般函數(shù)相同。友元類:整個類可以是另一個類的友元。友元類的每個成員函數(shù)都是另一個類的友元函數(shù),都可訪問另一個類中的保護或私有數(shù)據(jù)成員。定義方法如下:class A friend class B; /聲明B為A的友元類 ;2022/9/20計算機基礎(chǔ)教研室77一個類的所有對象具有相同的屬性;描述類的所有對象的共同特征的一個數(shù)據(jù)項,對于任何對象實例,它的屬性值是相同的。4.7 靜態(tài)成員2022/9/20計算機基礎(chǔ)教研室784.7 靜態(tài)成員 在類定義中,用關(guān)鍵字static修飾的數(shù)成員為靜態(tài)成員。包括靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù)。 類的所有對象共享由系統(tǒng)為靜態(tài)數(shù)據(jù)成員分配的一個存儲空間,而這個存儲空間是在編譯時分配的,在定義對象時不再為靜態(tài)數(shù)據(jù)成員分配空間。 靜態(tài)數(shù)據(jù)成員

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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

提交評論