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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

2、使用面向對象的觀點來描述模仿并處理現實問題。面向對象技術中的對象就是現實世界中某個具體的物理實體在計算機邏輯中的映射和體現。2022/9/20計算機基礎教研室6對象類計算機世界實體類別現實世界客觀世界抽象抽象實例化映射主觀世界對象、實體與類現實世界中的實體可以抽象出類別的概念。對應于計算機世界就有一個類(class)的概念。面向對象就是計算機世界模擬現實世界。現實世界與計算機世界的映射關系2022/9/20計算機基礎教研室7對象對 象面向對象編程的核心為計算機應用程序提供實用基礎完成特定任務表示現實世界中的實體“對象是存在的具體實體,具有明確定義的狀態(tài)和行為?!?022/9/20計算機基礎教研

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

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

5、符的個數。2022/9/20計算機基礎教研室14結構化程序與面向對象程序的比較問題:輸入圓的半徑,求圓的周長和面積數據描述:半徑,周長,面積均用實型數表示數據處理:輸入半徑 r;計算周長 = 2*r ;計算面積 = * r2 ;輸出半徑,周長,面積; 2022/9/20計算機基礎教研室15方法一:用結構化方法編程,求圓的周長和面積#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計算機基礎教研室16方法二:用面向對象方法編程,求圓的周長和面積 實例化分析“圓”是抽象的類類型建立具體的圓(對象)半徑?圓的周長 ? 面積 ?2022/9/20計算機基礎教研室17方法二:用面向對象方法編程,求圓的周長和面積 圓類 屬性 半徑 方法 置半徑值取半徑值求周長 求面積實例化分析2022/9/20計算機基礎教研室18方法二:用面向對象方法編程,求圓的周長和面積#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類數據成員成員函數建立對象(類類型的變量)通過對象調用類的成員函數2022/9/20計算機基礎教研室19類與對象的基本概念 4.1.3 對象的創(chuàng)建與使用 4.1.1 C+類的定義

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

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

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

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

13、24類CGoods成員函數的定義void CGoods:RegisterGoods(char name , int amount , float price) strcpy(Name , name) ; /字符串復制函數 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計算機基礎教研室25定義對象: 對象是類的實例(instance)。定義一種數據類型只是告訴編譯系統(tǒng)該數據類型的構造,并沒有預定內存。類只是一個樣板,以此樣板可以在內存中開辟出同樣結構的實例對象。格式如下:CGoods Car; 這個定義創(chuàng)建了CGoods類的一個對象Car,同時為它分配了屬于它自己的存儲塊,用來存放數據和對這些數據實施操作的成員函數(代碼)。對象只在定義它的域中有效。4.1.3

15、 對象的創(chuàng)建與使用 2022/9/20計算機基礎教研室26數據區(qū)對象1數據區(qū)對象數據區(qū)對象公共代碼區(qū) 系統(tǒng)為每個對象分配一個數據區(qū),公共代碼區(qū)(放成員函數的區(qū)域)為各對象共用。 注意: 區(qū)別同一個類的各個不同對象是由數據成員決定的;操作的代碼對所有對象都是一樣的。 通過sizeof計算對象占用的存儲空間時不包括函數代碼所占用的存儲空間。 對象的存儲2022/9/20計算機基礎教研室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 類定義數據成員聲明成員函數聲明回顧 用面向對象方法編程,求圓的周長和面積 2022/9/20計算機基礎教研室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; 回顧 用面向對象方法編程,求圓的周長和面積 成員函數實現2022/9/20計算機基礎教研室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 ; 建立對象(類類型變量)通過對象調用類的成員函數回顧 用面向對象方法編程,求圓的周長和面積 2022/9/20計算機基礎教研室30內聯(lián)函數: 在類定義外部定義的成員函數之前可以使用inline關鍵字說明其為內聯(lián)函數;在類定義中定義的成員函數則可以省略inline,系統(tǒng)將自動是其為內聯(lián)函數。 如Get_Area()函數可定義為:inline double Circle:Get_Area() return 3.14f * radius * radius; 注意:inline只是一個建議,最后由編譯器決定是否執(zhí)行。對象的存儲方式是物理的,

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

20、函數允許為內聯(lián)函數、重載函數、帶默認參數值的函數。4.3.1 構造函數的定義與使用2022/9/20計算機基礎教研室33函數名與類名相同。構造函數無函數返回類型說明。注意是什么也不寫,也不可寫void。構造函數可以在類中定義,也可以在類外定義。構造函數可以重載,系統(tǒng)在自動調用時按一般函數重載的規(guī)則選一個執(zhí)行。構造函數的特征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計算機基礎教研室34如果類定義中沒有給出構造函數,則編譯器自動給出一個默認的構造函數: 類名( ) 但只要定義了一個構造函數,系統(tǒng)就不會自動生成默認的構造函數。如果定義的構造函數是無參的或各參數均有默認值的,編譯器會認為其是默認的構造函數,默認的構造函數只能有一個 。建立新對象時,該對象所屬的類的構造函數自動被調用,并且在其生命期中只調用一次。構造函數的特征2022/9/2035#include using namespace std;class Q int x, y;public: Q(int a, int b) cout構造函數Q(a, b)

22、endl; x=a; y=b; Q(int a) cout構造函數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();輸出:構造函數Q(a,b)50100構造函數Q(a)500構造函數舉例 2022/9/20計算機基礎教研室36析構函數特征: 當一個對象的生命周期結束時,C+會自動調用析構函數對該對象并進行善后工作。1.構函數名與類名相同,但在前面加上字符 ,如:CGoods()2.析構函數無函數返回類型,與構造函數在這方面是一樣的,但析構函數

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

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

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

26、* radius;2022/9/20計算機基礎教研室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;運行結果:Enter the radius of the pool: 10Fencing Cost is ¥2858.85Concrete Cost is ¥4335.392022/9/20計算機基礎教研室414.4.1 引用 4.4.2 復制構造函數 4.4.3 成員對象與構造函數 4.4 引用與復制構造函數2022/9/20計算機基礎教研室42引用的導入: 傳值方式的參數傳遞是在函數域中為形參分配內存,而把實參的數值傳遞到新分配的內存中。

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

29、類型變量分配內存空間 。 在程序中修改了newnum也就是修改了number,兩位一體。 引用主要用于函數之間的數據傳遞。44【例4.3】引用作為形參 Xyd1d2temp1.4142.7181.4142.7181.414參數d1、d2為引用時內存分配示意 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、對象在內存中有完全相同的結構,如果作為一個整體進行復制是完全可行的。這個復制過程只需要復制數據成員,而成員函數是共用的。 在建立對象時可用同一類的另一個對象來初始化該對象,這時所用的構造函數稱為復制構造函數。復制構造函數復制構造函數的特征:1. 復制構造函數的參數必須采用引用。2.系統(tǒng)會自動提供稱為默認的按成員語義支持的復制構造函數,亦稱為默認的按成員初始化。按成員作復制是通過依次復制每個數據成員實現的。3.同類對象之間可以用賦值運算符 = 直接復制。2022/9/20計算機基礎教研室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);/調用三個參數的構造函數CGood Car2 = Car1; /調用復制構造函數CGood Car3 (Car1); /調用復制構造函數,Car1為實參這樣三個對象的初始化結果完全一樣。復制構造函數 當成員函數的參數為同一類(class)的對象或它的引用,在函數體內使用參數對象的私有數據成員時,可用對象名加成員訪問操作符點號進行。 從邏輯上講,每個對象有自己的成員函數,訪問同類其他對象的私有數據成員應

32、通過該對象的公有函數,不能直接訪問。但在物理上只有一個成員函數代碼,所以直接訪問是合理的。僅在成員函數中可以這樣做。2022/9/20計算機基礎教研室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復制構造函數被調用endl;復制構造函數舉例2022/9/20計算機基礎教研室48(1)當用

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

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

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

36、Lineprivate: Point p1, p2; /線段的兩個端點 double s; /線段的長度public: Line(Point a, Point b); /構造函數聲明,無初始化區(qū);2022/9/20計算機基礎教研室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); 類聚合構造函數實例Line:Line(Point a, Point b):p1(a

37、), p2(b), s(0)2022/9/20計算機基礎教研室55 含對象成員的析構函數: 因為析構函數沒有參數,所以包含成員對象的類的析構函數形式上并無特殊之處。但是撤銷該類對象時,會首先調用自己的析構函數,再調用成員對象的析構函數,調用次序與初始化時的次序相反。成員對象與構造函數2022/9/20計算機基礎教研室56【例4.6】含有成員對象的類的構造函數#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計算機基礎教研室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;運行結果為:賦給學生的學號: 82020132學生名:朱明

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

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

41、=com.image; void print() coutreal+imageiendl; ;2022/9/20計算機基礎教研室60inline complex:complex(complex &com)/復制構造函數的定義 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計算機基礎教研室61運行結果:Initializing 0 0 /全局對象global建立,調默認的構造函數Entering main /進入入口函數mainInitializing 0 0 /用默

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

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

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

46、少應該有一個是自定義類型。運算符重載的規(guī)則和限制2022/9/20計算機基礎教研室65重載為成員函數,解釋為:ObjectL.operator+ (ObjectR) 左操作數由ObjectL通過this指針傳遞,右操作數由參數ObjectR傳遞 ObjectL + ObjectR 二元運算符+ 語法形式為:類型 類名 : operator op(參數表) /相對于該類定義的操作 operator是關鍵字,它與重載的運算符op一起構成函數名。2022/9/20計算機基礎教研室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); /重載+運算符函數 Complex operator+(double); /重載+運算符函數 Complex operator=(Complex); /重載=運算符函數; Complex Complex:operator+(Complex c)/重載+ Complex Temp(Re

48、al+c.Real , Image+c.Image) ; return Temp; 【例4.8】復數類,應用它進行復數運算2022/9/20計算機基礎教研室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后面跟的表達式中調用的是類的構造函數,它為新建的作為返回值載體的無名對象進行初始化。 2022/9/20計算機基礎教研室68運算符的重載引用作為參數: Complex Complex:o

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

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

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

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

54、基礎教研室74例4.8_1】 用友元函數重載運算符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計算機基礎教研室75Complex &operator +=(Complex &c1,const Complex &c2) /重載復數+= c1.Real = c1.Real + c2.Real; c1.Image = c1.Image + c2.Image; return c1; /返回由引用參數傳遞過來的變量,函數返回值可為引用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(); /兩復數相加 c+=c2+=c1; c.Print(); /連續(xù)加賦值 c=c+d; c.Print(); /復數加實數 c=d+c; c.Print(); /實數加復數 return 0;2022/9/20計算機基礎教研室76友元函數注意點: 1.友元函數不是類的成員函數,在函數體中訪問對象的成員,必須用

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

溫馨提示

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

評論

0/150

提交評論