版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
一、運算符重載的概念
二、禁止重載的運算符
三、運算符重載的規(guī)則
四、單目運算符函數(shù)
五、雙目運算符函數(shù)第17章運算符重載1一、運算符重載的概念系統(tǒng)的運算符主要分兩大種類:一是單目運算符,另一是雙目運算符。用不屬于字符集的@代表各種許可的運算符,運算符構成的表達式抽象的表現(xiàn)格式為:
1.@x2.x@yx和y是運算符關聯(lián)的操作數(shù),其原先可以出現(xiàn)的數(shù)據(jù)類型是算術類型以及相關的指針類型如char*,CType*等。僅當存在運算符函數(shù),操作數(shù)x或y才可以是對象。能轉換為運算符函數(shù)的普通函數(shù)或單參數(shù)的函數(shù),此時稱單目運算符函數(shù);或雙參數(shù)的函數(shù),此時稱雙目運算符函數(shù).2原來普通的雙參數(shù)(非靜態(tài)的成員函數(shù)隱含this參數(shù))函數(shù):intCType::Add(intk){returnn+k;}intSub(CTypea,intk){returna.n-k;}可以相應地改寫為運算符函數(shù)(其中n是CType類的int型數(shù)據(jù)成員):intCType::operator+(intk){returnn+k;}intoperator-(CTypea,intk){returna.n-k;}關鍵字operator是實現(xiàn)普通函數(shù)轉換為運算符函數(shù)的語法中介,operator@是運算符函數(shù)名。當@分別對應+-*/時加分別得到四個運算符函數(shù),依次是operator+加號運算符函數(shù)、operator-減號運算符函數(shù)、operator*乘號運算符函數(shù)和operator/除號運算符函數(shù)。3運算符重載是簡化對象運算的函數(shù)調用現(xiàn)象,通過定義函數(shù)名為operator@的運算符函數(shù),有關對象的函數(shù)調用可以簡化為x@y或@x隱含調用的替代形式。 運算符函數(shù)operator@可以存在多個版本,只要編譯器根據(jù)名稱細分的結果在函數(shù)調用點能夠進行唯一的匹配。
例如:iostream類中operator<<左移運算符函數(shù)就存在多個版本。 名稱為operator@的運算符函數(shù)可以是成員函數(shù)也可以是全局函數(shù)。基于解除私有封裝的考慮,全局函數(shù)聲明為類的友員函數(shù)。如果類只有公共成員,則無需聲明為友員函數(shù)。作為非虛的成員運算符函數(shù)和全局運算符函數(shù)的重載在編譯階段完成函數(shù)調用的確定,virtual關鍵字可以修飾作為成員的運算符函數(shù)。4[例]普通函數(shù)和相應的運算符函數(shù)#include<stdio.h>structCType{intn;CType(intr=1){n=r;}intoperator+(intk){returnn+k;}intAdd(intk){returnn+k;}};intoperator-(intk,CTypea){returnk-a.n;}intSub(intk,CTypea){returnk-a.n;}voidmain(){ CTypea(0),b(-7); printf("%d,%d,%d;",a+1,a.operator+(1),a.Add(1));printf("%d,%d,%d\n",1-b,operator-(1,b),Sub(1,b));}//輸出:1,1,1;8,8,85含對象的表達式a+1等價于顯式調用a.operator+(1),a+1是CType::operator+(int)的隱含調用,隱含調用方便了對象的操作。類似地隱含調用1-b等價于operator-(1,b)的顯式調用。1+a不同于a+1,1+a要求匹配operator+(int,CType)型的全局運算符函數(shù),而b-1要求匹配operator-(CType,int)型的全局函數(shù)或CType::operator-(int)型的成員函數(shù)。由于上例題未提供相應的函數(shù),1+a和b-1此情形下是錯誤的表達式。6二、禁止重載的運算符
只有區(qū)區(qū)五個運算符不可以賦予運算符的函數(shù)實現(xiàn),它們是:
.
.*
::
sizeof
?:圓點訪問成員運算符”.”,對象訪問成員指針運算符”.*”,這兩個運算符分別是箭頭訪問成員運算符->和對象指針訪問成員指針運算符->*的翻版為對象訪問成員保留一條安全的入口。作用域分別符::和sizeof運算符都是編譯階段發(fā)揮作用。sizeof運算符的入口參數(shù)本身可以是各種類型名。另一個是三目條件運算符?:,這個運算符本身是if~else嵌套結構的合理重載。7三、運算符重載的規(guī)則存在兩種運算符函數(shù)的調用格式,一種是將運算符函數(shù)當作函數(shù)名為operator@的顯式調用格式,另一種是隱含調用格式,最終編譯器在內部轉換為顯式調用格式。操作數(shù)x,y是算術或指針類型,表達式x@y,@x是常規(guī)的算術或指針運算,不涉及運算符函數(shù)。x或y是對象,x@y隱含調用相應的雙目運算符函數(shù);x是對象,@x隱含調用相應的單目運算符函數(shù);若不存在相應的運算符函數(shù),隱含調用導致錯誤。對于一個特定的類,系統(tǒng)提供等號運算符函數(shù)operator=和取地址運算符函數(shù)operator&供程序調用,即對于該類的對象x,y可以進行運算:x=y,&x。8對于對象表達式的前臺隱含操作,必須存在一個無歧義的運算符函數(shù)作為背景支持。如果無相應的運算符函數(shù)或類型轉換函數(shù),則有關對象的隱含調用導致錯誤。
例如:x+=y是毫無根基的運算,除非存在相關的operator+=運算符函數(shù)。語句[CType*p;]定義的指針p不是對象而是一個常規(guī)的指針,對于變量指針合適的運算符也可作用于對象之指針。 運算符始終遵循內部類型所規(guī)定的優(yōu)先原則、結合性。即對于出現(xiàn)在表達式中的運算符函數(shù)隱含調用如x@y,@x,優(yōu)先級高的運算符函數(shù)優(yōu)先被編譯器隱含調用,同等級別的運算符函數(shù)根據(jù)結合性進行分解處理。9非靜態(tài)的成員運算符函數(shù)的第一個參量對應隱含this的當前類的類型。類型轉換運算符、函數(shù)調用運算符()、數(shù)組下標索引運算符[]、箭頭運算符->函數(shù)和等號運算符函數(shù)只作為非靜態(tài)的成員函數(shù),其余的運算符可以和operator緊貼在一起構成全局函數(shù)。等號運算符函數(shù)operator=不為派生類繼承。
不能憑空捏造C++語言中子虛烏有的運算符如FORTRAN語句的乘冪運算符**。運算符函數(shù)不允許用戶提交缺省的默認值,函數(shù)調用運算符operator()例外。
10雙目或單目全局運算符函數(shù)形參類型至少存在一個用戶聲明的類型,枚舉類只能有全局運算符函數(shù)。 例如對于類聲明[structCType{};],CType或CType&是用戶聲明的類型。CType*類型為常規(guī)的指針類型,不用于構成運算符函數(shù)的對象類型。voidoperator*(CType&,int){}是正確的函數(shù)定義,而voidoperator-(CType*,int){}與voidoperator+(char,int){}是錯誤的??梢栽诼暶鞯念惿蠈\算符函數(shù)提交任意的語義實現(xiàn)。但出于與內置類型表達式的接口考慮,最好按照運算符固有含義進行運算符函數(shù)定義。11四、單目運算符函數(shù)單目運算符中存在格外的運算符,這就是成為C++由來的后置運算符。這個運算符從后面作用于操作數(shù),其運算符重載有其特殊的格式。對于語句[CTypeobj;]定義的對象obj,單目運算符函數(shù)隱含調用的格式為@obj。
121.單目成員運算符函數(shù)聲明時不帶參量,編譯器隱含補充this參量。聲明格式為:
ret_typeoperator@();返回類型單目運算符函數(shù)名();在類外定義的格式為:
ret_typeCType::operator@(){語句序列;}
隱含調用@obj轉換為顯式調用obj.operator@()。非靜態(tài)的單目成員運算符函數(shù)隱含的形參this在調用點由&obj賦予具體的值。132.單目全局運算符函數(shù)僅帶一個用戶聲明的類型,聲明格式為:
ret_typeoperator@(CType&r);
在實現(xiàn)文件的定義格式為:
ret_typeoperator@(CType&r){顯含形參r的語句序列;}隱含調用@obj轉換為顯式調用operator@(obj)。單目全局運算符函數(shù)形參r在調用點由obj賦予具體的值,若需要訪問CType類的私有成員則聲明為該類的友元函數(shù)。 @()成員版本也可調用operator@(obj)全局版本。為避免重載的歧義性,只提交一種版本,或者是成員版本,或者是全局版本。14[例]重載邏輯非運算符!負號運算符-和前置運算符++
staticintm=1;#include<stdio.h>classCType{intn;friendCType&operator++(CType&q);friendvoidmain();friendCTypeoperator-(constCType&r);public:CType(intr){n=r;}intoperator!();};
intCType::operator!(){printf("%d!,",m++);return!n;}15 CTypeoperator-(constCType&r){printf("%d-,",m++);returnCType(-r.n);}CType&operator++(CType&q){printf("%d++,",m++);++q.n;returnq;}voidmain(){ CTypea(2),b(-1); a=!-++b;printf("a=%d\n",a.n);a=(operator-(operator++(b))).operator!(); printf("a=%d",a.n);}//a=1先調用構造函數(shù)CType(int)即a=1相當于a=CType(1)++b等價于operator++(b),-++b等價于operator-(operator++(b))等。16五、雙目運算符函數(shù)
雙目運算符函數(shù)如果是非靜態(tài)的成員函數(shù)則聲明的時候僅帶一個參量,編譯器隱含的補充一個this參量。如果聲明為全局函數(shù),則雙目運算符函數(shù)帶兩個參量,其中一個參量的類型必須是一個用戶聲明的類型。
171.雙目成員運算符函數(shù) 作為成員的雙目運算符函數(shù)的聲明格式為:
ret_typeoperator@(type);返回類型雙目運算符函數(shù)名(數(shù)據(jù)類型);在類外定義的格式為:
ret_typeCType::operator@(typearg){語句序列;}對于定義語句[CTypeobj;]設定的對象obj和type型表達式var,隱含調用的格式為:
obj@var隱含調用obj@var轉換為obj.operator@(var)的顯式調用形式。非靜態(tài)的雙目成員運算符函數(shù)隱含的形參this在調用點由&obj賦予具體的值,實參var負責形參arg的初始化。182.雙目全局運算符函數(shù) 雙目全局運算符函數(shù)由于接口的需要花樣增多一倍,相應的聲明格式為:
ret_typeoperator@(CType&r,typearg);
//此格式可以從成員版本變換而來返回類型雙目運算符函數(shù)名(當前類名,其它類名);
ret_typeoperator@(typearg,CType&r);返回類型雙目運算符函數(shù)名(其它類名,當前類名);相應的隱含調用的格式為:
obj@varvar@obj19obj@var轉換為顯式調用operator@(obj,var)即啟動operator@(CType&r,typearg)函數(shù),var@obj轉換為顯式調用operator@(var,obj)即啟動operator@(typearg,CType&r)函數(shù),形參r由對象名obj初始化,實參var賦予形參arg具體的初值。 @(var)也可調用全局版本operator@(obj,var)。兩者本質上應是等價的,因此酌情提交一個版本,以免導致歧義。20[例]重載加減乘除運算符實現(xiàn)結構變量的四則運算#include<stdio.h>structCA{CAoperator+(CAb);CA(intr=1){n=r;};intn;};staticintm=1;CACA::operator+(CAa){printf("%d+,",m++);returnCA(n+a.n);}CAoperator-(CAa,constCA&r){printf("%d-,",m++);returnCA(a.n-r.n);}CAoperator*(CAa,CAb){printf("%d*,",m++);returnCA(a.n*b.n);}CAoperator/(constCA&r,constCA&q){printf("%d/,",m++);returnCA(r.n/q.n);}21voidmain(){ CAa,b(2),c(6);a=(a+b)*(c/b)-b;printf("a=%d;",a.n);a=operator-((operator*(a.operator+(b),operator/(c,b))),b);printf("a=%d;",a.n);}
//輸出:1/,2+,3*,4-,a=7;5/,6+,7*,8-,a=25;
22對于對象的引用返回,引用是已經(jīng)建立的對象的別名,返回的是不獨立的對象,此時編譯器不需要額外建立臨時對象。對于對象的數(shù)值返回,返回一個局部或臨時的獨立對象,輸送給主控
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版物流行業(yè)預付款擔保合同2篇
- 二零二五版搬家服務與家政服務融合合同樣本2篇
- 二零二五年度蔬菜電子商務合同:線上銷售平臺與賣家之間的規(guī)則2篇
- 二零二五版汽車零部件購銷合同標準及售后服務模板3篇
- 二零二五年度國際教育機構合作辦學合同3篇
- 二零二五年度高壓變壓器安裝及安全防護技術合同3篇
- 二零二五版社保繳納與工傷保險待遇保障合同3篇
- 二零二五年度租賃合同:辦公設備的長期租賃與維護2篇
- 二零二五版板材綠色包裝設計與材料供應合同3篇
- 二零二五年度酒店改造項目投資合同范本3篇
- 《項目施工組織設計開題報告(含提綱)3000字》
- ICU常見藥物課件
- CNAS實驗室評審不符合項整改報告
- 農民工考勤表(模板)
- 承臺混凝土施工技術交底
- 臥床患者更換床單-軸線翻身
- 計量基礎知識培訓教材201309
- 中考英語 短文填詞、選詞填空練習
- 阿特拉斯基本擰緊技術ppt課件
- 初一至初三數(shù)學全部知識點
- 新課程理念下的班主任工作藝術
評論
0/150
提交評論