c課件運算符重載和類重載.ppt
《c課件運算符重載和類重載.ppt》由會員分享,可在線閱讀,更多相關《c課件運算符重載和類重載.ppt(51頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、第12章 運算符重載和類型重載,主要內(nèi)容: 12.1 運算符重載規(guī)則 12.2 類型重載,在C++中有這樣的情況,同一個類型或運算符在不同的類中代表不同的意思或者實施不同的運算,這就是面向?qū)ο蟮娜筇攸c之一的多態(tài)。 函數(shù)重載是C++語言中多態(tài)的一種表現(xiàn)形式,運算符重載和類型重載是多態(tài)的另外兩種表現(xiàn)形式。,運算符重載是對已有的運算符賦予多重含義。 C++中預定義的運算符的操作對象只能是基本數(shù)據(jù)類型,對于很多用戶自定義類型,也需要有類似的運算操作,這就提出了對運算符進行重新定義,賦予已有符號以新功能的要求。 同一個運算符作用于不同類型的數(shù)據(jù)導致不同的行為。,12.1 運算符重載概述,運算符
2、重載只能對系統(tǒng)提供的已有運算定義新的運算含義,不能創(chuàng)造全新的運算符,同時還不能改變運算符原有的語法結構、操作數(shù)個數(shù)、優(yōu)先級和結合性,不能有二義性。不是所有的運算符都能重載,不能重載的運算符有:作用域運算符(::)、條件運算符(?:)、直接成員訪問運算符(.)、sizeof運算符、解除對指向類成員的指針的引用運算符(.*)。 運算符重載的關鍵字是operator。針對一個具體類的已有運算符重載有兩種途徑: 1)將運算符重新定義為類的成員函數(shù); 2)將運算符重新定義為類的友元函數(shù)。,一、運算符重載方法,定義一個重載運算符就像定義一個函數(shù),只是該函數(shù)的名字是operator,這里代表運算符。函
3、數(shù)參數(shù)表中參數(shù)的個數(shù)取決于兩個因素: 1) 運算符是一元的(一個參數(shù))還是二元的(兩個參數(shù))。 2) 運算符被定義為友元函數(shù)(對于一元是一個參數(shù),對于二元是兩個參數(shù))還是成員函數(shù)(對于一元沒有參數(shù),對于二元是一個參數(shù)對象變?yōu)樽髠葏?shù))。,1.將運算符重載為類的成員函數(shù),將運算符重載為類的成員函數(shù)就是在類中用關鍵字operator定義一個成員函數(shù),函數(shù)名就是重載的運算符。運算符如果重載為類的成員函數(shù),它就可以自由地訪問該類的數(shù)據(jù)成員。 運算符重載為類的成員函數(shù)的一般格式為: :: operator (形參表) 函數(shù)體 其中,類型為運算符重載函數(shù)的返回類型。類名為成員函數(shù)所屬類的類
4、名,即為重載函數(shù)名。形參為參加運算的對象或數(shù)據(jù)。,【例題12.1】 復數(shù)的加減運算符重載,#include using namespace std; class Complex private: float real,image; public: Complex(float r=0,float i=0); Complex Add(const Complex ,Complex::Complex(float r,float i) real=r; image=i; void Complex::Show(int i) //一般情況下,這里不應該有參數(shù)i,本例的目的是為了區(qū)分不同的復數(shù)
5、,便于觀看結果 cout0) cout<<+< 6、 c2.Show(2); c5=c1-c2; c5.Show(5); return 0; ,如果我們把“operator+”看成函數(shù)名,可以在main()函數(shù)中寫出如下語句: c3=c1.Add(c2); c3=c1.operator+(c2); 這時,operator+就完全是一個函數(shù)了(它本質(zhì)上就是函數(shù)),.Add()和operator+的作用和功能完全相同,只是表現(xiàn)形式有些區(qū)別。,【例題12.2】一元運算符重載,在Time類(描述時間的類,用三個數(shù)據(jù)成員分別存放時、分和秒)中重載自加運算符,即一個時間加上n秒后形成一個新的的時間。,class Time private: 7、 int hour,minute,second; public: Time(int h=0,int m=0,int s=0); //其他構造函數(shù)省略 如Time(Time,Time::Time(int h,int m,int s) hour=h; minute=m; second=s; void Time::Show() cout< 8、60) second=0; minute++; if(minute==60) minute=0; hour++; if(hour==24) hour=0; return temp; ,Time ,int main() Time t1(10,25,52),t2,t3; t1.Show(); t2=++t1; t1.Show(); t2.Show(); t3=t1++; t3.Show(); t1.Show(); ,對于++(或--)運算符的重載,因為編譯器不能區(qū)分出++(或--)是前置的還是后置的,所以要加上(int)來區(qū)分。 ope 9、rator++(); //重載前置++ operator++(int); //重載后置++ operator--(); //重載前置-- operator--(int); //重載后置--,運算符重載的一些特點如下: (1) 運算符重載函數(shù)名必須為:operator。 (2) 運算符的重載是通過運算符重載函數(shù)來實現(xiàn)的。對于二元運算符重載函數(shù),函數(shù)的參數(shù)通常為一個即右操作數(shù),運算符的左操作數(shù)為調(diào)用重載函數(shù)的對象。對于一元運算符重載函數(shù),運算符的左操作數(shù)或右操作數(shù)為調(diào)用重載函數(shù)的對象。 (3) 運算符重載函數(shù)的返回類型:若對象進行運算后的結果類型仍為原類型,則運算符重載函數(shù)的返回類型應為原類型。, 10、【例11.3】 自定義字符串類String中有一個private成員p_str指向一個C格式的字符串,寫出其拷貝構造函數(shù),并重載賦值“=”運算符。,#include #include using namespace std; class String public: String()p_str=NULL; String(const String ,String::String(const char *str) p_str=new charstrlen(str)+1; strcpy(p_str,str); String::String(const String ,String ,賦 11、值運算符重載一般包括以上幾個步驟,首先要檢查是否自賦值,如果是要立即返回,如果不返回,后面的語句會把自己所指空間刪掉,從而導致錯誤;第二步要釋放原有的內(nèi)存資源;第三步要分配新的內(nèi)存資源,并復制內(nèi)容;第四步是返回本對象的引用。如果沒有指針操作,則沒有第二步操作。 賦值運算符與拷貝構造函數(shù)在功能上有些類似,都是用一個對象去填另一個對象,但拷貝構造函數(shù)是在對象建立的時候執(zhí)行,賦值運算符是在對象建立之后執(zhí)行。,2將運算符重載為類的友元函數(shù),二元運算符重載為友元函數(shù)的一般格式為: friend operator (, ); operator (, ) 函數(shù)體; 一元運算符重載為友元函數(shù)的一般格式為: 12、operator (類名 class Complex private: float real,image; public: Complex(float r=0,float i=0); friend Complex operator+( const Complex ,Complex::Complex(float r,float i) real=r; image=i; void Complex::Show(int i) cout0) cout<<+< 13、operator+( const Complex ,int main() Complex c1(12,35),c2(20,46),c3,c4; c1.Show(1); c2.Show(2); c3=c1+c2; c3.Show(3); c4=c1-c2; c4.Show(4); return 0; ,【例11.5】用友元運算符重載函數(shù)實現(xiàn)時間類的“++”運算符。,class Time public: Time(int h=0,int m=0,int s=0); //其他構造函數(shù)省略 void Show();//顯示時:分:秒的成員函數(shù) friend Time,3 14、. 參數(shù)和返回值,1) 對于任何函數(shù)參數(shù),如果僅需要從參數(shù)中讀而不改變它,缺省地應當按const引用來傳遞它。普通算術運算符(像+和-號等)和布爾運算符不會改變參數(shù),所以以const引用傳遞是使用的主要方式。當函數(shù)是一個類成員的時候,就轉換為const成員函數(shù)。只是對于會改變左側參數(shù)的賦值運算符(像+ =)和運算符=,左側參數(shù)才不是常量( constant ),但因為參數(shù)將被改變,所以參數(shù)仍然按地址傳遞。 2) 應該選擇的返回值取決于運算符所期望的類型。如果運算符的效果是產(chǎn)生一個新值,將需要產(chǎn)生一個作為返回值的新對象。,3) 所有賦值運算符改變左值。為了使得賦值結果用于鏈式表達式(像A = 15、B = C),應該能夠返回一個剛剛改變了的左值的引用。但這個引用應該是const還是nonconst呢?雖然我們是從左向右讀表達式A = B = C,但編譯器是從右向左分析這個表達式,所以并非一定要返回一個nonconst值來支持鏈式賦值。然而人們有時希望能夠?qū)倓傎x值的對象進行運算,例如(A = B). foo( ),這是B賦值給A后調(diào)用foo( )。因此所有賦值運算符的返回值對于左值應該是nonconst引用。 4) 對于邏輯運算符,人們希望至少得到一個int返回值,最好是bool返回值。(在大多數(shù)編譯器支持C + +內(nèi)置bool類型之前開發(fā)的庫函數(shù)使用int或typedef等價物)。 16、 5) 當有不同類型的參數(shù)時,要注意參數(shù)的自動類型轉換(稱為隱式類型轉換),隱式類型轉換在很多地方可以簡化程序的書寫,但是也可能留下隱患。,【例11.6】在Complex類中重載運算符+,使該類對象能加上一個復數(shù)形成一個新的復數(shù),能加上一個整數(shù)或加上一個實數(shù)形成一個新的復數(shù)。,#include using namespace std; class Complex private: float real,image; public: Complex(float r=0,float i=0); Complex operator+(const Complex ,int main() 17、 Complex c1(12,35),c2(20,46),c3,c4,c5,c6; int i=5; float f=7.7; c1.Show(1); c2.Show(2); c3=c1+i; //編譯正確 c3.Show(3); c4=c1+f; //編譯正確 c4.Show(4); c5=c1+1.5; //編譯錯誤,可用c5=c1+(int)1.5;或者 c5=c1+(float)1.5; c5.Show(5); return 0; ,在進行運算符重載時,我們要注意: 1)重載不能改變該運算符用于內(nèi)置類型時的含義,正如程序員不能改變運算符+用于兩個int型相加時的含 18、義。 2)運算符函數(shù)的參數(shù)至少有一個必須是類的對象或者類的對象的引用,這種規(guī)定可以防止程序員運用運算符改變內(nèi)置類型的函義。 3)重載不能改變運算符的優(yōu)先級。 4)重載不能改變運算符的結合律。 5)重載不能改變運算符操作數(shù)的個數(shù)。比如+需要兩個操作數(shù),則重載的+也必須要有兩個操作數(shù)。 6)不存在用戶定義的運算符,即不能編寫目前運算符集合中沒有的運算符。不能這樣做的部分原因是難以決定其優(yōu)先級,另一部分原因是沒有必要增加麻煩。,當一個重載操作符的含義不明顯時,給操作取一個名字更好。對于很少用的操作,使用命名函數(shù)通常比用操作符更好。如果不是普通操作,沒必要為簡潔而使用操作符。 重載逗號、取地址、邏輯 19、與、邏輯或等操作符通常不是好做法。這些操作符具有有用的內(nèi)置含義,如果我們定義了自己的版本,就不能再使用這些內(nèi)置含義。 如果類定義了相等操作符,也應該定義不等操作符!=。同樣,如果定義了,=,<,<=)。,為類設計重載操作符的時候,必須選擇是將操作符設置為類成員函數(shù)還是友元函數(shù)。在某些情況下,程序員沒得選擇,操作符必須是成員函數(shù)。有些指導原則有助于決定將操作符設置為類成員還是友元函數(shù): 1)賦值(=)、下標()、調(diào)用(( ))和成員訪問箭頭(-)等操作符必須定義為成員,將這些操作符定義為非成員函數(shù)在編譯時標記為錯誤。 2)像賦值一樣,復合賦值操作符通常應定義為類的成員函數(shù)。定義成非成員函數(shù)不會 20、出現(xiàn)編譯錯誤。 3)改變對象狀態(tài)或與給定類型緊密聯(lián)系的其他一些操作符,如自增、自減等通常定義為類成員函數(shù)。 4)對稱的操作符,如算術操作符、相等操作符、關系操作符和位操作符,最好定義為非成員函數(shù)。,istream 和 ostream 是 C++ 的預定義流類,cin 是 istream 的對象,cout 是 ostream 的對象。運算符 由 istream 重載為提取操作, 用于輸出和輸入基本類型數(shù)據(jù)。可用重載 運算符 ,用于輸出和輸入用戶自定義的數(shù)據(jù)類型,必須定義為類的友元函數(shù)。,4. 重載流插入和流提取運算符,1)輸出操作符<<的重載 輸出操作符重載函數(shù)形式為: ostream 第一 21、個參數(shù)和函數(shù)的類型都必須是ostream class Date public: Date(int y,int m,int d); bool isLeapYear(); void print(); friend ostream #endif // DATE_H_INCLUDED,【例11.7】為Date類重載提取運算符(ex004.cpp),#include #include Date.h using namespace std; Date::Date(int y,int m,int d) year=y; month=m; day=d; bool Date::isLeap 22、Year() return (year%4==0 ,void Date::print() cout<< year<<-<< month<<-<< day< 23、函數(shù)(main)中, cout的值被傳遞給output。由于函數(shù)返回的是ostream對象的引用,所以在主函數(shù)中可以將”<<”連接起來使用。,2輸入操作符的重載 輸入操作符重載函數(shù)形式為: istream 與輸出操作符類似,輸入操作符的第一個形參是一個引用,指向要讀的流,并且返回的也是同一個流的引用。第二個形參是對要讀入的對象的非const 引用,該形參必須為非const,因為輸入操作符的目的是將數(shù)據(jù)讀到這個對象中。和輸出操作符不同的是輸入操作符必須處理錯誤和文件結束的可能性。,【例題11.8】重載輸入操作符,在上例的基礎上加上Date類對象能用“”輸入數(shù)據(jù)。,class Date p 24、ublic: Date()year=0;month=0;day=0; Date(int y,int m,int d); Date(string s); bool isLeapYear(); private: int year; int month; int day; friend ostream,istream ,int main() Date d1(2013,3,20); coutd2; cout< 25、輸入了字符型數(shù)據(jù),讀入以及流的后續(xù)使用都將失敗。 2)任何讀入都可能碰到輸入流中的文件結束或其他一些錯誤。 如果輸入操作符檢測到輸入失敗了,則確保對象處于可用和一致的狀態(tài)是個好做法。如果對象在錯誤發(fā)生之前已經(jīng)寫入了部分信息,這樣做就特別重要。因此設計輸入操作符時,如果可能,要確定錯誤恢復措施,這是很重要的。例題11.8中如果輸入出現(xiàn)錯誤,將對象中的數(shù)據(jù)成員都設置為0,使得對象仍然處于可用狀態(tài),同時也不會產(chǎn)生令人誤解的結果。,12.2類型重載,C++中提供了類型轉換函數(shù),可以將一種類類型對象轉換成另一種類類型的對象,這就是類型重載。類型轉換函數(shù)必須由用戶在類中定義為成員函數(shù),其一般格式為: 26、class public: operator ( ); ; ::operator () 函數(shù)體; 其中operator 為轉換函數(shù)的函數(shù)名,轉換函數(shù)的作用是將類型1的對象轉換成類型2的對象。類中類型轉換函數(shù)必須是非靜態(tài)的成員函數(shù),不能定義成友元函數(shù),無返回值類型且不帶參數(shù)。,【例11.9】定義一個時間類,類中數(shù)據(jù)成員為時、分、秒。編寫類型轉換函數(shù),將時、分、秒變成一個以秒為單位的等價實數(shù)。,#include using namespace std; class Time private: int hour,minute,second; public: 27、 Time(int h=0,int m=0,int s=0); void Show();//顯示時:分:秒的成員函數(shù) operator float(); ; Time::Time(int h,int m,int s) hour=h; minute=m; second=s; ,void Time::Show() cout<
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 110中國人民警察節(jié)(筑牢忠誠警魂感受別樣警彩)
- 2025正字當頭廉字入心爭當公安隊伍鐵軍
- XX國企干部警示教育片觀后感筑牢信仰之基堅守廉潔底線
- 2025做擔當時代大任的中國青年PPT青年思想教育微黨課
- 2025新年工作部署會圍繞六個干字提要求
- XX地區(qū)中小學期末考試經(jīng)驗總結(認真復習輕松應考)
- 支部書記上黨課筑牢清廉信念為高質(zhì)量發(fā)展營造風清氣正的環(huán)境
- 冬季消防安全知識培訓冬季用電防火安全
- 2025加強政治引領(政治引領是現(xiàn)代政黨的重要功能)
- 主播直播培訓直播技巧與方法
- 2025六廉六進持續(xù)涵養(yǎng)良好政治生態(tài)
- 員工職業(yè)生涯規(guī)劃方案制定個人職業(yè)生涯規(guī)劃
- 2024年XX地區(qū)黨建引領鄉(xiāng)村振興工作總結
- XX中小學期末考試經(jīng)驗總結(認真復習輕松應考)
- 幼兒園期末家長會長長的路慢慢地走