欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    《運算子覆載》PPT课件.ppt

    • 资源ID:5650950       资源大小:279KB        全文页数:81页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    《運算子覆載》PPT课件.ppt

    1,第十四章,運算子覆載,2,第十四章 運算子覆載,在C+語言中,程式設計師除了可以對函式(包含成員函式)進行覆載之外,也可以對運算符號進行覆載,以擴充運算符號的功能,此稱為運算子覆載(Operator Overloading)。當然由於運算子分為單元運算子、二元運算子、前置運算子、後置運算子,因此運算子的覆載也比函式覆載稍微複雜一些,因此我們將運算子覆載獨立出來在本章作詳細的介紹。,3,大綱,14.1運算子覆載的需求14.2運算子覆載14.3單元運算子的覆載14.4二元運算子的覆載14.5單元運算與二元運算同時存在的覆載14.6 轉型運算子的覆載14.6.1物件轉基本資料型態14.6.2不同類別型態間的轉換14.7=與=運算子覆載14.7.1=運算子覆載14.7.2=運算子覆載14.8運算子覆載14.8.1運算子覆載14.9本章回顧,4,在前面的章節中,我們使用運算子進行運算時,使用的都是運算子內定的功能,例如基本的四則運算子:加+、減-、乘*、除/,比較運算子的比較運算:大於、等於=、小於 等等。舉例來說,如果要進行兩個整數a,b的相加,則只要透過加號運算子+即可完成,也就是a+b,之所以能夠如此做,是因為C/C+編譯器已經內建了+運算子的數學加法功能。事實上,+運算子原本就已經具有內定的覆載功能,因為它不但能進行整數的相加,還能進行浮點數的相加,甚至它還能夠自行依照資料型態作自動轉型的動作。雖然+運算子的功能已經非常強大,但它仍無法對我們所定義的結構體及類別(物件)進行運算,這是因為編譯器並不了解應該如何對這些由程式設計師所定義的資料型態作運算才是適當的。例如變數a與變數b為複雜的矩陣Matrix類別所產生的物件,編譯器對於a+b就不知道該如何解決。,14.1運算子覆載的需求,5,14.1運算子覆載的需求,為了使程式設計更方便,C+允許某些運算子被另行定義一些新功能,以便處理由程式設計師所定義的資料型態,這就是運算子覆載的主要目的。【註】:在上述範例中,當然我們也可以於Matrix類別中定義一個Matrix Sum(Matrix Var)成員函式,並透過c=a.Sum(b);完成矩陣的相加,但這卻不如c=a+b;來得方便與直觀,因此運算子覆載仍有其必要性及方便性。,圖14-1 運算子覆載的必要性,6,14.2運算子覆載,我們已經了解運算子覆載的用途後,本節將介紹如何實作運算子覆載。事實上,運算子覆載的實作方法與定義類別中的成員函式覆載相似,也就是在類別內宣告覆載運算子,以及在類別內或類別外具體定義覆載運算子的新運算行為。覆載運算子需要先在類別內宣告,其宣告語法如下:語法說明:(1)語法中的#代表的是運算子符號,例如+、-、-等等。(2)運算子的運算可以區分為不需要回傳值及需要回傳值。若不需要回傳值,則回傳資料型態應宣告為void。,回傳資料型態 operator#(傳入引數);,7,14.2運算子覆載,(3)傳入引數與函式的傳入引數類似,但有些不同。運算子的運算對象可以區分為單元運算(例如傳統的a+;)及二元運算(例如傳統的a+b;)。如果是二元運算則後面的運算元(第二個運算元)需設定為引數(前面的運算元不必設定為引數,因為這是在類別內定義,因此該類別的物件將自動隱含成為第一個運算元)。如果是單元運算,則又可以分為兩種狀況,如下所述。(4)單元運算分為兩種狀況,一種是前置運算子(例如傳統的+a;),一種是後置運算子(例如傳統的a+;)。宣告前置運算子覆載時不需要指定引數,宣告後置運算子覆載時則需要設定引數為int。(5)運算子的覆載還有一些限制如下:,8,限制一:覆載運算子需符合C+語法。限制二:程式設計師無法新創運算子符號,只能針對C+原有的運算符號進行覆載,同時有些運算子是無法被覆載的,整理如下:,14.2運算子覆載,表14-1 可進行覆載的運算子,9,14.2 運算子覆載,限制三:在可被覆載的運算子中,有些運算子只能被定義為單元運算子,如下表:限制四:在可被覆載的運算子中,有些運算子可以被定義為單元運算子或二元運算子,如下表:,表14-2 不可進行覆載的運算子,表14-3 只能被定義為單元運算子,表14-4 可被定義為單元運算子或二元運算子,10,14.2運算子覆載,限制五:無法重新定義運算元的個數(如限制四與限制三的規定)。限制六:無法重新定義運算子優先權。限制七:無法覆蓋運算子的原有功能。也就是內建的資料型態無法使用運算子覆載重新定義,例如下列語法欲重新定義兩浮點數相加是錯誤的語法。,11,14.2運算子覆載,當宣告運算子覆載後,即可在類別外定義運算子覆載的內容,語法如下:語法說明:我們也可以將宣告與定義合併於類別內,此時就不需指定類別名稱。而事實上,覆載運算子函式也屬於該類別的一個成員函式,我們稱之為覆載函式或覆載成員函式。,回傳資料型態 類別名稱:operator#(傳入引數)定義運算子覆載的運算行為;,12,14.3單元運算子的覆載,在本節中,我們將介紹單元運算子的覆載,單元運算子分為前置運算子與後置運算子兩種,首先我們先複習第三章所介紹的前置運算子與後置運算子定義。前置運算子(例如:+i):運算元進行加一或減一的動作後,再進行其他運用。後置運算子(例如:i+):運算元先進行其他運用,再進行加一或減一的動作。對於前置運算子而言,其覆載宣告語法如下:對於後置運算子而言,其覆載宣告語法如下:,回傳資料型態 operator#();,回傳資料型態 operator#(int);,13,14.3單元運算子的覆載,語法說明:(1)前置運算子覆載宣告與後置運算子覆載宣告的分別在於是否有傳入引數int(int是固定語法,無法修改為其他如float等資料型態)。(2)前置運算子與後置運算子的運算內容可以不同。(3)若無回傳資料,則回傳資料型態為void,此時若前置運算子與後置運算子的行為相同,則無論是前置運算子或後置運算子都不會影響整個運算式的結果。(4)若有回傳資料,則應該宣告回傳資料的資料型態,此時前置運算子應先進行運算行為,再回傳資料;後置運算子則應回傳原有資料再進行運算行為(這需要一些技巧)。,14,14.3單元運算子的覆載,範例:【觀念範例14-1】:宣告及定義單元運算子+的覆載,使得對自訂類別Matrix2D具有運算功能,扮演前置運算子,將進行累加2,扮演後置運算子,將進行累加3。不論是前置或後置運算子都不會回值資料。範例14-1:ch14_01.cpp(檔案位於隨書光碟 ch14ch14_01.cpp)。,15,16,14.3單元運算子的覆載,17,14.3單元運算子的覆載,執行結果:範例說明:(1)第1519行是+前置運算子的覆載定義。(2)第2025行是+後置運算子的覆載定義。(3)第42行的+ObjA會呼叫第1519行的覆載定義。(4)第48行的ObjB+會呼叫第2025行的覆載定義。(5)當我們覆載了+運算子之後,編譯器會根據作用運算元的資料型態來決定運算方法,舉例如下:,ObjA=|2,2|2,2|-ObjB=|3,3|3,3|,18,14.3單元運算子的覆載,在範例14-1中,若後置運算子也設定為矩陣內容+2,則由執行結果中,將看不出來後置運算子與前置運算子的差別,這是因為我們並要求覆載的前置或後置運算子回傳資料。事實上,如果我們讓覆載的前置或後置運算子回傳資料,也能夠讓前置運算子與後置運算子的效果有所不同。舉例來說,在C+中,若+作為前置運算子,則會先進行加一的動作後,再將結果回傳。若+作為後置運算子,則會先傳遞變數值,然後才進行加一的動作。如下圖:,19,14.3單元運算子的覆載,圖14-2 前置運算子與後置運算子的差別,20,14.3單元運算子的覆載,【觀念及實用範例14-2】:參考+運算子的原意,覆載+的前置與後置運算子功能,使其可適用於Matrix2D類別的矩陣遞增運算。範例14-2:ch14_02.cpp(檔案位於隨書光碟 ch14ch14_02.cpp)。,21,22,14.3單元運算子的覆載,23,14.3單元運算子的覆載,24,14.3單元運算子的覆載,執行結果:範例說明:(1)第1519行是+前置運算子的覆載定義。它會回傳一個Matrix2D類別的物件,由於前置運算子的原意是先進行運算再回傳運算結果,因此,回傳時只要將原本物件內容回傳即可,因此,我們透過this指標達成這項工作。(2)第2026行是+後置運算子的覆載定義。雖然後置運算子的原意和前置運算子的原意恰好相反,但我們卻無法單純地將第17、18行的順序對調作為覆載運算定義,因為這會先遇到return而造成遞增運算未被執行,故我們先使用TempObj存放原始矩陣內容,最後也是回傳TempObj,以符合後置運算子的原意。,原本ObjA=|0,0|0,0|ObjB=|0,0|0,0|經ObjB=+ObjA;運算後ObjA=|1,1|1,1|ObjB=|1,1|1,1|=原本ObjC=|0,0|0,0|ObjD=|0,0|0,0|經ObjD=ObjC+;運算後ObjC=|1,1|1,1|-ObjD=|0,0|0,0|,25,14.4二元運算子的覆載,除了少數的單元運算子,絕大多數的運算子都屬於二元運算子,也就是運算元有兩個,例如A%B的%取餘數就是一個二元運算子,其運算元有A與B兩個。在覆載二元運算子時,由於我們一定是定義在某類別內,因此,必定有一個物件是內定的運算元,在傳統加法中,被加數就是那一個運算元,例如ObjA+ObjB,我們應該把+運算子覆載在ObjA的所屬類別內。除了內定的運算元外,二元運算子的另一個運算元的資料型態則必須明確定義於覆載運算子的宣告中,因此,覆載二元運算子的宣告語法如下:語法說明:(1)二元運算一般都具有回傳值,如果沒有回傳值則可將回傳資料型態設為void。(2)宣告時,變數名稱可以省略,但定義時變數名稱不可省略,而且通常該變數會在函式內被使用。,回傳資料型態 operator#(另一個運算元的資料型態 變數名稱);,26,14.4二元運算子的覆載,舉例來說,假設X、Y、Z皆是Matrix2D類別的物件,其運算子呼叫運算子覆載函式的示意圖如下:,圖14-3 二元運算子覆載示意圖,27,14.4二元運算子的覆載,【觀念及實用範例14-3】:將Matrix2D矩陣類別(矩陣元素資料型態修正為double),加入二元運算子*乘法功能,乘法對象可以是矩陣,也可以是實數。其中矩陣相乘公式如下:範例14-3:ch14_03.cpp(檔案位於隨書光碟 ch14ch14_03.cpp)。,28,29,14.4二元運算子的覆載,30,14.4二元運算子的覆載,31,14.4二元運算子的覆載,執行結果:範例說明:(1)第20行,宣告覆載*運算子,使其能夠應用於Matrix2D類別,進行矩陣*數學常數的運算,其定義(運算行為)紀錄於第2736行。(2)第21行,宣告覆載*運算子,使其能夠應用於Matrix2D類別,進行矩陣*矩陣的運算,其定義(運算行為)紀錄於第3746行。(3)第62行會呼叫第2736行(3將會被變數R接收,而this將指向物件ObjA)進行矩陣*數學常數的運算,並將回傳值存放於ObjC中。(4)第65行會呼叫第3746行(ObjB將會被物件變數R接收,而this將指向物件ObjA)進行矩陣*矩陣的運算,並將回傳值存放於ObjD中。,ObjA=|2,4|6,8|ObjB=|1,9|4,16|-ObjC=ObjA*3=|6,12|18,24|ObjD=ObjA*ObjB=|18,82|38,182|,32,14.5 單元運算與二元運算同時存在的覆載,不知讀者是否發現一個問題,單元運算的後置運算必須將傳遞引數設為int,而二元運算則必須將第二個運算元設為引數。這在允許進行單元運算及多元運算的運算子時(如-,*),是否可能會造成混淆?請回顧範例14-3的第20行,如果我們將其運算對象設為整數(int),並將運算子改為-號,請問我們想要進行的是負號單元運算子的覆載,還是減號二元運算子的覆載呢?答案其實很簡單,因為同時允許進行單元運算及二元運算覆載的運算子是無法進行後置運算子覆載的,例如我們通常會以-a代表負a,而不會以a-代表負a,因此,下列語法代表宣告的是覆載-二元運算子,其引數代表第二個運算元為整數(絕對不是代表覆載-後置單元運算子)。,33,14.5 單元運算與二元運算同時存在的覆載,在解答上述疑惑後,同一符號的單元運算覆載與多元運算覆載就變得單純多了,我們只要遵守14.2節的限制四即可。以下,我們透過範例實作-的負號覆載與減法覆載。【觀念及實作範例14-4】:-的負號覆載(單元前置運算子)與減法覆載(二元運算子)。範例14-4:ch14_04.cpp(檔案位於隨書光碟 ch14ch14_04.cpp)。,34,35,14.5 單元運算與二元運算同時存在的覆載,36,14.5 單元運算與二元運算同時存在的覆載,37,14.5 單元運算與二元運算同時存在的覆載,執行結果:範例說明:(1)第20行,宣告覆載-運算子的前置運算覆載,其定義(運算行為)記錄於第2736行。(2)第21行,宣告覆載-運算子的二元運算覆載,其定義(運算行為)記錄於第3746行。(3)第62行會呼叫第2736行進行矩陣*(-1)的運算,並將回傳值存放於ObjC中。(4)第65行會呼叫第3746行進行矩陣-矩陣的運算,並將回傳值存放於ObjD中。,ObjA=|2,4|6,8|ObjB=|1,9|4,16|-ObjC=-ObjA=|-2,-4|-6,-8|ObjD=ObjA-ObjB=|1,-5|2,-8|,38,14.6 轉型運算子的覆載,()是一種非常特殊的運算子,它通常用在引數的宣告或運算式優先權的改變,在這些狀況下,它是無法被覆載的。除此之外,()若搭配某種資料型態,還可以使用在強制型別轉換,在C語言及C+語言中,強制型別轉換具有不同的語法格式,假設A為整數變數,B為浮點數,欲將B的數值設定給A,C與C+的語法如下:C語法 C+語法A=(int)B;A=int(B);()的強制型別轉換不但可以轉換為基本資料型態,也可以用在轉換結構體與類別的自訂型態轉換。當()使用在強制型別轉換時,它是可以被覆載的運算子,但僅限於C+語法的型別轉換,因為運算子覆載是C+提供的功能,C語言並不存在這種能力。,39,14.6 轉型運算子的覆載,當然,對於()的強制型別轉換需求可能有下列四種狀況:狀況一:從基本資料型別轉換為基本資料型別。這是C+原有功能,無法也不需要被覆載。狀況二:從基本資料型別轉換為自訂資料型別。這是C+原有功能,無法也不需要被覆載。狀況三:從自訂資料型別轉換為基本資料型別。可以在類別內宣告為覆載。於節中說明。狀況四:從自訂資料型別轉換為自訂資料型別。可以在類別內宣告為覆載。於節中說明。如果現在A為浮點變數,但是B為程式設計師自行定義的向量類別物件,主要用來儲存某個向量的x與y軸的分量,我們是否能利用類似上面的轉型動作,來求出此向量的長度呢?在C+語言中,答案是可以的,我們可以利用()運算子的覆載,讓物件也具有這種轉型功能,我們將在本節中加以說明。,40,14.6.1物件轉基本資料型態,當我們欲將物件強制轉型為基本資料型態時,其回傳值必定是某一種指定的基本資料型態(例如float型態)。事實上,由於物件包含的成員變數可能不只一個,通常我們會想要將多筆資料換算成單一筆資料,都是發生在欲求出某種具有意義的數值時才會使用,例如求出最大值max(),但基本資料型別的名稱都已經固定,因此,將物件強制轉型為基本資料型態的案例並不多見。(例如我們想要求出物件成員變數的最大值,會以成員函式max()來加以解決。)暫且不論物件轉基本資料型態的實際用途為何!C+仍提供了此一功能,其語法如下:覆載轉型運算子()的宣告語法如下(轉為基本資料型態):覆載轉型運算子()的定義語法如下(轉為基本資料型態):,類別名稱:operator 欲轉換的基本資料型態().轉換方式 return 欲轉換型態的變數或常數;,operator 欲轉換的基本資料型態();,41,14.6.1物件轉基本資料型態,語法說明:(1)宣告必須在類別內。宣告與定義可以合併在類別內,此時就不需要指定類別名稱。(2)轉換資料型態一定會有回傳值,但不需要指定回傳值的資料型態,因為回傳值的資料型態就是欲轉換的基本資料型態。(3)轉換方式可以是任何合法的程式內容,您可以直接將某個成員變數經由轉型後回傳,或經過複雜的運算後,再決定要回傳什麼資料。(4)假設物件A為float浮點數,B為Matrix2D類別的物件,下圖可說明覆載()運算子執行的過程。,圖14-4 覆載強制轉型運算子()示意圖,42,14.6.1物件轉基本資料型態,【觀念範例14-5】:覆載double()運算子,使物件也具有轉換資料的能力,其轉換過程為,取出成員變數中的最大值,並且將之乘以2倍後回傳(如果該值非double型態,則必須先將之轉型為double型態)。範例14-5:ch14_05.cpp(檔案位於隨書光碟 ch14ch14_05.cpp)。,43,44,14.6.1物件轉基本資料型態,45,14.6.1物件轉基本資料型態,執行結果:範例說明:(1)第20行,宣告覆載轉型運算子(),轉型後的資料型態為double,其定義(運算行為)記錄於第2736行。(2)第51行會呼叫第2736行進行轉型,並將回傳值存放於X中。依據題意及程式內容,X將會是ObjA成員變數中最大值的兩倍。,ObjA=|1.3,7.5|9.7,6.2|X=19.4,46,14.6.2不同類別型態間的轉換,類別強制轉型運算子的覆載,在物件轉物件時(兩物件隸屬不同類別)通常比較有幫助,例如,我們可能希望將2x2矩陣物件轉型為3x3矩陣物件(將原有元素保留,其餘填0)。在C+中,類別轉類別型態的語法如下:覆載轉型運算子()的宣告語法如下(轉為自訂類別資料型態):覆載轉型運算子()的定義語法如下(轉為自訂類別資料型態):語法說明:語法與轉基本資料型態類似,只不過將之改為已宣告過的合法類別名稱。,類別名稱:operator 欲轉換的類別資料型態().轉換方式 return 欲轉換類別的物件;,operator 欲轉換的類別資料型態();,47,14.6.2不同類別型態間的轉換,【觀念範例14-6】:覆載()運算子,使Matrix22物件可轉換為Matrix33物件,轉換後原有元素將以兩倍出現,而新元素將被設定為100。範例14-6:ch14_06.cpp(檔案位於隨書光碟 ch14ch14_06.cpp)。,48,14.6.2不同類別型態間的轉換,49,14.6.2不同類別型態間的轉換,50,14.6.2不同類別型態間的轉換,51,14.6.2不同類別型態間的轉換,執行結果:,ObjA=|164,177|155,189|ObjB=|328,354,100|310,378,100|100,100,100|,52,14.6.2不同類別型態間的轉換,範例說明:(1)第23行,宣告覆載轉型運算子(),轉型後的資料型態為Matrix33,其定義(運算行為)記錄於第5158行,其中產生TempObj物件時,會呼叫Matrix33的建構函式(第3542行)。(2)第80行會呼叫第5158行進行轉型,並將回傳值存放於ObjB中。依據題意及程式內容,ObjB的各元素將會ObjA各元素的兩倍,其餘則補100。,53,=運算子在C+中的原意是設定,=運算子在C+中的原意是比較是否相等,這兩個運算子的使用率極高,我們將在本節中介紹這兩個運算子的覆載。,14.7=與=運算子覆載,54,14.7.1=運算子覆載,在C+中,=運算子的設定功能原本就非常強大,它除了可以進行基本資料型態的設定之外,還可以進行結構體或物件的設定。一般來說,在=左右的資料型態如果相同,它都能夠準確地將=右邊的資料設定給左邊的變數。如果=左右的資料型態不相同時,則會依照內定模式進行自動資料轉型(如第三章所述),通常只有基本資料型態才具有自動轉型能力,若欲將基本資料型態轉型並指定給物件,則需要在類別內覆載=運算子。覆載=運算子的宣告語法如下:覆載=運算子的定義語法如下:,void 類別名稱:operator=(等號右邊的資料型態).覆載內容,void operator=(等號右邊的資料型態);,55,14.7.1=運算子覆載,語法說明:(1)宣告必須在類別內。宣告與定義可以合併在類別內,此時就不需要指定類別名稱。而所謂類別名稱代表的是=運算子左邊的物件變數所屬的類別,例如:X=A;,則應該在X所屬類別內進行上述宣告,至於A的資料型態則應該宣告在()內。(2)通常只有在運算式=左右的資料型態不同時才會作上述的覆載。但若=左右的資料型態相同時,也可以作上述的覆載,而這可能會改變了=運算子設定的原意。(3)覆載=運算子不需要回傳值,所以宣告為void,不過如果您宣告了回傳值,也不會影響程式正確性,因為該回傳值不會被使用。【觀念範例14-7】:覆載=運算子,使得能夠設定double變數給Matrix2D物件。範例14-7:ch14_07.cpp(檔案位於隨書光碟 ch14ch14_07.cpp)。,56,57,58,14.7.1=運算子覆載,執行結果範例說明:(1)第20行,宣告覆載=運算子,可適用於Matrix2D物件=double變數或常數,其定義(運算行為)記錄於第2632行,將傳入值分別*1、*2、*3、*4指定給成員變數。(2)第46行ObjB=ObjA;的=維持原有設定之意。但第49行ObjC=X;的=則會呼叫第2632行的覆載行為。,ObjA=|2,4|6,8|ObjB=ObjA=|2,4|6,8|ObjC=X=|0.8,1.6|2.4,3.2|,59,在C+中,=運算子的比較是否相等功能僅限於基本資料型態的比較,如果=的左邊是物件,則必須在類別內覆載=運算子。覆載=運算子的宣告語法如下:覆載=運算子的定義語法如下:,14.7.2=運算子覆載,bool 類別名稱:operator=(雙等號右邊的資料型態).覆載內容 return true或false;,bool operator=(雙等號右邊的資料型態);,60,14.7.2=運算子覆載,語法說明:(1)宣告必須在類別內。宣告與定義可以合併在類別內,此時就不需要指定類別名稱。而所謂類別名稱代表的是=運算子左邊的物件變數所屬的類別,例如:X=A;,則應該在X所屬類別內進行上述宣告,至於A的資料型態則應該宣告在()內。(2)在上述語法中,為了維持=運算子的原意,因此我們將回傳值資料型態設定為bool。【實用及觀念範例14-8】:覆載=比較運算子,使得能夠比較兩個物件是否相等(若成員變數完全相同,視為相等)。同時也覆載=比較運算子,使得能夠比較物件與基本資料型態是否相等(物件內的成員變數都與基本資料型態變數相同時,才視為相等)。範例14-8:ch14_08.cpp(檔案位於隨書光碟 ch14ch14_08.cpp)。,61,62,14.7.2=運算子覆載,63,64,14.7.2=運算子覆載,執行結果範例說明:(1)第19行,宣告覆載=運算子,可適用於Matrix2D物件=Matrix2D物件的比較,其定義(運算行為)記錄於第2633行。(2)第20行,宣告覆載=運算子,可適用於Matrix2D物件=double變數或常數,其定義(運算行為)記錄於第3441行。(3)第48、53行的比較運算式將呼叫第2633行的覆載行為。第58、63行的比較運算式將呼叫第3441行的覆載行為。,ObjA與ObjB不相等ObjA與ObjC相等ObjC與X不相等ObjD與X相等,65,14.8運算子覆載,上述介紹的覆載運算子都有一個特性,就是不需要和其他類別合作即可完成。雖然我們並未介紹所有的運算子覆載,但其餘運算子的覆載技巧大多大同小異,除了本節要介紹的之外。,66,14.8.1運算子覆載,標準函式庫提供的C+-style字串(也就是string類別衍生的物件)。明顯地,C+編譯器若只引入函式庫,它將不知道如何應該輸出C+-style字串,但在引入標準函式庫後,C+編譯器便能夠了解要輸出C+-style字串的哪些資料。而這正是因為標準函式庫內覆載了string類別的運算子。,67,14.8.1運算子覆載,看起來,我們如果想要利用ostream、ofstream等輸出類別輸出自訂類別的物件資料,只要在自訂類別中覆載運算子即可,但事實並非如此單純,因為實際負責輸出資料動作的並非只有我們自訂的類別,ostream、ofstream等輸出類別也必須能具備存取我們自行定義類別中私有資料的能力。因此,我們必須透過友誼技巧,將覆載時宣告為友誼運算子才行,換句話說,原本代表覆載內容的成員函式必須被宣告為友誼函式。覆載運算子的宣告語法如下:覆載運算子的定義語法如下:,ostream,friend ostream,68,14.8.1運算子覆載,語法說明:(1)宣告時必須加上關鍵字friend,宣告此運算子為友誼運算子(也就是該函式為友誼函式),以便存取另一個類別中的私有變數。例如運算子可能會需要存取ostream類別及欲輸出的資料類別的私有變數,當加上friend之後,覆載運算子與ostream類別及欲輸出的資料類別將成為朋友,就能夠突破私有變數存取的限制了。(2)定義時並不需要加上類別名稱,雖然我們宣告覆載運算子是在欲輸出的資料類別中加以宣告,但由於是友誼函式,因此並不屬於任何類別。(3)在引數宣告中,我們宣告了一個ostream類別的參考物件out、以供我們使用。由於cout也屬於ostream類別的內定物件,因此,在使用out物件時,可以使用所有關於cout物件的語法,因為它們同屬同一類別。【實用及觀念範例14-9】:覆載運算子,使它具有輸出物件成員變數(含私有成員)的能力。範例14-9:ch14_09.cpp(檔案位於隨書光碟 ch14ch14_09.cpp)。,69,70,14.8.1運算子覆載,執行結果:範例說明:(1)第19行,透過友誼方式宣告覆載運算子,可與ostream類別的物件合作進行輸出資料,其定義(運算行為)記錄於第2530行。(2)第36行,使用cout物件時(cout物件隸屬於ostream類別)可順利輸出ObjA的資料成員(由第2530行完成此一工作)。,ObjA=|1.3,7.5|9.7,6.2|,71,14.8.2運算子覆載,運算子的覆載與通常使用在資料的輸入,需要與istream類別的物件cin配合,覆載語法如下。覆載運算子的宣告語法如下:覆載運算子的定義語法如下:,istream,friend istream,72,14.8.2運算子覆載,語法說明:宣告時也需要宣告為友誼覆載函式,語法和,類別改為istream(in是隸屬於istream類別的物件)。此外,為了在呼叫覆載函式時,能夠共用記憶體以儲存資料,因此,我們必須將輸入物件採傳參考方式傳遞。【實用及觀念範例14-10】:覆載運算子,使它具有輸入物件成員變數(含私有成員)的能力。範例14-10:ch14_10.cpp(檔案位於隨書光碟 ch14ch14_10.cpp)。,73,74,14.8.2運算子覆載,執行結果:,a11=5a12=6a21=7a22=8ObjA=|5,6|7,8|,75,14.8.2運算子覆載,範例說明:(1)第20行,透過友誼方式宣告覆載運算子,可與istream類別的物件合作進行輸入資料,其定義(運算行為)記錄於第2638行。(2)第48行,使用cin物件時(cin物件隸屬於istream類別)可順利輸入ObjA的資料成員(由第2638行完成此一工作)。,76,14.9本章回顧,在本章中,我們介紹許多關於運算子覆載的技巧,並實作了許多範例,重點整理如下:(1)在C+語言中,程式設計師除了可以對函式(包含成員函式)進行覆載之外,也可以對運算符號進行覆載,以擴充運算符號的功能,此稱為運算子覆載(Operator Overloading)。(2)覆載運算子需要先在類別內宣告,其宣告語法如下:(3)當宣告運算子覆載後,即可在類別外定義運算子覆載的內容,語法如下:,回傳資料型態 類別名稱:operator#(傳入引數).定義運算子覆載的運算行為.;,回傳資料型態 operator#(傳入引數);,77,14.9本章回顧,(4)運算子的覆載有一些限制如下:限制一:覆載運算子需符合C+語法。限制二:程式設計師無法新創運算子符號,只能針對C+原有的運算符號進行覆載,同時有些運算子是無法被覆載的。詳見表14-2。限制三:在可被覆載的運算子中,有些運算子只能被定義為單元運算子。詳見表14-3。限制四:在可被覆載的運算子中,有些運算子可以被定義為單元運算子或二元運算子。詳見表14-4。限制五:無法重新定義運算元的個數(如限制四與限制三的規定)。限制六:無法重新定義運算子優先權。限制七:無法覆蓋運算子的原有功能。也就是內建的資料型態無法使用運算子覆載重新定義。,78,14.9本章回顧,(5)對於前置運算子的覆載而言,其宣告語法如下:對於後置運算子的覆載而言,其宣告語法如下:(6)覆載二元運算子的宣告語法如下:(7)覆載轉型運算子()的宣告語法如下(轉為基本資料型態):覆載轉型運算子()的宣告語法如下(轉為自訂類別資料型態):,回傳資料型態 operator#();,回傳資料型態 operator#(int);,回傳資料型態 operator#(另一個運算元的資料型態 變數名稱);,operator 欲轉換的基本資料型態();,operator 欲轉換的類別資料型態();,79,14.9本章回顧,(8)覆載=運算子的宣告語法如下:(9)覆載=運算子的宣告語法如下:(10)覆載運算子,由於跨類別,因此需要透過friend宣告為友誼覆載函式。覆載運算子的宣告語法如下:覆載運算子的定義語法如下:,void operator=(等號右邊的資料型態);,bool operator=(雙等號右邊的資料型態);,ostream,friend ostream,80,14.9本章回顧,覆載運算子的宣告語法如下:覆載運算子的定義語法如下:,istream,friend istream,81,本章習題,

    注意事项

    本文(《運算子覆載》PPT课件.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开