C++單目運算符重載
單目運算符只有一個操作數,如!a,-b,&c,*p,還有最常用的++i和--i等。重載單目運算符的方法與重載雙目運算符的方法是類似的。但由于單目運算符只有一個操作數,因此運算符重載函數只有一個參數,如果運算符重載函數作為成員函數,則還可省略此參數。
下面以自增運算符”++“為例,介紹單目運算符的重載。
[例] 有一個Time類,包含數據成員minute(分)和sec(秒),模擬秒表,每次走一秒,滿60秒進一分鐘,此時秒又從0開始算。要求輸出分和秒的值。
#include <iostream>using namespace std;class Time{ public: Time( ){minute=0;sec=0;} //默認構造函數 Time(int m,int s):minute(m),sec(s){ } //構造函數重載 Time operator++( ); //聲明運算符重載函數 void display( ){cout<<minute<<":"<<sec<<endl;} //定義輸出時間函數 private: int minute; int sec;};Time Time::operator++( ) //定義運算符重載函數{ if(++sec>=60) { sec-=60; //滿60秒進1分鐘 ++minute; } return *this; //返回當前對象值}int main( ){ Time time1(34,0); for (int i=0;i<61;i++) { ++time1; time1.display( ); } return 0;}運行情況如下:
34:134:2┆34:5935:035:1 (共輸出61行)
可以看到:在程序中對運算符“++”進行了重載,使它能用于Time類對象。“++”和“--”運算符有兩種使用方式,前置自增運算符和后置自增運算符,它們的作用是不一樣的,在重載時怎樣區別這二者呢?
針對“++”和“--”這一特點,C++約定,在自增(自減)運算符重載函數中,增加一個int型形參,就是后置自增(自減)運算符函數。
[例] 在上面例子程序的基礎上增加對后置自增運算符的重載。修改后的程序如下:
#include <iostream>using namespace std;class Time{ public: Time( ){minute=0;sec=0;} Time(int m,int s):minute(m),sec(s){} Time operator++( );//聲明前置自增運算符“++”重載函數 Time operator++(int);//聲明后置自增運算符“++”重載函數 void display( ){cout<<minute<<":"<<sec<<endl;} private: int minute; int sec;};Time Time::operator++( )//定義前置自增運算符“++”重載函數{ if(++sec>=60) { sec-=60; ++minute; } return *this;//返回自加后的當前對象}Time Time::operator++(int)//定義后置自增運算符“++”重載函數{ Time temp(*this); sec++; if(sec>=60) { sec-=60; ++minute; } return temp; //返回的是自加前的對象}int main( ){ Time time1(34,59),time2; cout<<" time1 : "; time1.display( ); ++time1; cout<<"++time1: "; time1.display( ); time2=time1++; //將自加前的對象的值賦給time2 cout<<"time1++: "; time1.display( ); cout<<" time2 :"; time2.display( ); //輸出time2對象的值}請注意前置自增運算符“++”和后置自增運算符“++”二者作用的區別。前者是先自加,返回的是修改后的對象本身。后者返回的是自加前的對象,然后對象自加。請仔細分析后置自增運算符重載函數。
運行結果如下:
time1 : 34:59(time1原值)++time1: 35:0 (執行++time1后time1的值)time1++: 35:1 (再執行time1++后time1的值)time2 : 35:0 (time2保存的是執行time1++前time1的值)
可以看到,重載后置自增運算符時,多了一個int型的參數,增加這個參數只是為了與前置自增運算符重載函數有所區別,此外沒有任何作用。編譯系統在遇到重載后置自增運算符時,會自動調用此函數。
C++雙目運算符重載
雙目運算符(或稱二元運算符)是C++中最常用的運算符。雙目運算符有兩個操作數,通常在運算符的左右兩側,如3+5,a=b,i<10等。在重載雙目運算符時,不言而喻在函數中應該有兩個參數。
[例] 定義一個字符串類String,用來存放不定長的字符串,重載運算符“==”、“<”和“>”,用于兩個字符串的等于、小于和大于的比較運算。
為了使讀者便于理解程序,同時也使讀者了解建立程序的步驟,下面分幾步來介紹編程過程:
1) 先建立一個String類:
#include <iostream>using namespace std;class String{ public: String( ){p=NULL;} //默認構造函數 String(char *str); //構造函數 void display( ); private: char *p;//字符型指針,用于指向字符串};String::String(char *str) //定義構造函數{p=str;} //使p指向實參字符串void String::display( ) //輸出p所指向的字符串{cout<<p;}int main( ){ String string1("Hello"),string2("Book"); string1.display( ); cout<<endl; string2.display( ); return 0;}運行結果為:
HelloBook
2) 有了這個基礎后,再增加其他必要的內容?,F在增加對運算符重載的部分。為便于編寫和調試,先重載一個運算符“>”。程序如下:
#include <iostream>#include <string>using namespace std;class String{ public: String( ){p=NULL;} String(char *str); friend bool operator>(String &string1,String &string2);//聲明運算符函數為友元函數 void display( ); private: char *p;//字符型指針,用于指向字符串};String::String(char *str){p=str;}void String::display( ) //輸出p所指向的字符串{cout<<p;}bool operator>(String &string1,String &string2)//定義運算符重載函數{ if(strcmp(string1.p,string2.p)>0) return true; else return false;}int main( ){ String string1("Hello"),string2("Book"); cout<<(string1>string2)<<endl;}程序運行結果為1。
這只是一個并不很完善的程序,但是,已經完成了實質性的工作了,運算符重載成功了。其他兩個運算符的重載如法炮制即可。
3) 擴展到對3個運算符重載。
在String類體中聲明3個成員函數:
friend bool operator> (String &string1, String &string2); friend bool operator< (String &string1, String &string2); friend bool operator==(String &string1, String& string2);
在類外分別定義3個運算符重載函數:
bool operator>(String &string1,String &string2) //對運算符“>”重載{ if(strcmp(string1.p,string2.p)>0) return true; else return false;}bool operator<(String &string1,String &string2) //對運算符“<”重載{ if(strcmp(string1.p,string2.p)<0) return true; else return false;}bool operator==(String &string1,String &string2) //對運算符“==”重載{ if(strcmp(string1.p,string2.p)==0) return true; else return false;}再修改主函數:
int main( ){ String string1("Hello"), string2("Book"), string3("Computer"); cout<<(string1>string2)<<endl; //比較結果應該為true cout<<(string1<string3)<<endl; //比較結果應該為false cout<<(string1==string2)<<endl; //比較結果應該為false return 0;}運行結果為:
100
結果顯然是對的。到此為止,主要任務基本完成。
4) 再進一步修飾完善,使輸出結果更直觀。下面給出最后的程序。
#include <iostream>using namespace std;class String{ public: String( ){p=NULL;} String(char *str); friend bool operator>(String &string1, String &string2); friend bool operator<(String &string1, String &string2); friend bool operator==(String &string1, String &string2); void display( ); private: char *p;};String::String(char *str){p=str;}void String::display( ) //輸出p所指向的字符串{cout<<p;}bool operator>(String &string1, String &string2){ if(strcmp(string1.p, string2.p)>0) return true; else return false;}bool operator<(String &string1, String &string2){ if(strcmp(string1.p, string2.p)<0) return true; else return false;}bool operator==(String &string1, String &string2){ if(strcmp(string1.p, string2.p)==0) return true; else return false;}void compare(String &string1, String &string2){ if(operator>(string1, string2)==1) {string1.display( );cout<<">";string2.display( );} else if(operator<(string1, string2)==1) {string1.display( );cout<<"<";string2.display( );} else if(operator==(string1, string2)==1) {string1.display( );cout<<"=";string2.display( );} cout<<endl;}int main( ){ String string1("Hello"), string2("Book"), string3("Computer"), string4("Hello"); compare(string1, string2); compare(string2, string3); compare(string1, string4); return 0;}運行結果為:
Hello>BookBook<ComputerHello==Hello
增加了一個compare函數,用來對兩個字符串進行比較,并輸出相應的信息。這樣可以減輕主函數的負擔,使主函數簡明易讀。
通過這個例子,不僅可以學習到有關雙目運算符重載的知識,而且還可以學習怎樣去編寫C++程序。由于C ++程序包含類,一般都比較長,有的初學C++的讀者見到比較長的程序就發怵,不知該怎樣著手去閱讀和分析它。輪到自己編程序,更不知道從何入 手,往往未經深思熟慮,想到什么就寫什么,一口氣把程序寫了出來,結果一運行,錯 誤百出,光為找出錯位置就花費了大量的時間。根據許多初學者的經驗,上面介紹的方法是很適合沒有編程經驗的初學者的,能使人以清晰的思路進行程序設計,減少出錯機會, 提高調試效率。
這種方法的指導思想是:先搭框架,逐步擴充,由簡到繁,最后完善。邊編程,邊調試,邊擴充。千萬不要企圖在一開始時就解決所有的細節。類是可擴充的,可以一步一步地擴充它的功能。最好直接在計算機上寫程序,每一步都要上機調試,調試通過了前面一步再做下一步,步步為營。這樣編程和調試的效率是比較高的。大家可以試驗一下。
新聞熱點
疑難解答
圖片精選