C++運算符的重載
課題目標
了解多態性,掌握運算符重載的種類,形式,與體現方式,學會重載運算符
課題內容
面向程序設計的優勢在於將派生類對象當基類對象一樣處理,這就是多態和動態綁定。
多態的類型
分為專用多態(重載多態,強制多態),通用多態(包含多態,參數多態)。
重載多態:主要是函數與類的成員函數的重載和運算符重載。
一,運算符重載
運算符重載是對已有的運算符賦予多重含義,使同一個運算符作用於不同類型的數據時導致不同的行為。
二,運算符重載的多態意義
我們了解的運算符的功能“ + ”、“ - ”、“ * ”、“ / ”可能單一,但就不同數據類型進行相同的操作,這就是多態的體現。
三,運算符重載的語法形式:
返回類型 operator op(參數){ //對應操作 }
operator:關鍵字
op:函數名
四,運算符重載的方式體現
1)普通運算符重載(“ + ”、“ - ”、“ * ”、“ / ”等)

1 #include <iostream> 2 using namespace std; 3 4 class Complex 5 { 6 private: 7 double real,imag; 8 public: 9 Complex(double r = 0.0, double i = 0.0); 10 void Print(); 11 Complex operator+(Complex a); 12 Complex operator-(Complex a); 13 14 }; 15 16 Complex::Complex(double r, double i) 17 { 18 real = r; 19 imag = i; 20 } 21 22 Complex Complex::operator+(Complex a) 23 { 24 Complex temp; 25 temp.real = real + a.real; 26 temp.imag = imag + a.imag; 27 return temp; 28 } 29 30 Complex Complex::operator-(Complex a) 31 { 32 Complex temp; 33 temp.real = real - a.real; 34 temp.imag = imag - a.imag; 35 return temp; 36 } 37 38 void Complex::Print() 39 { 40 cout <<real; 41 if(imag > 0) 42 cout << "+"; 43 if(imag != 0) 44 cout << imag << "i" <<endl; 45 } 46 47 int main() 48 { 49 Complex c1(1.1, 2.2), c2(3.3, 4.4),total; 50 total = c1 + c2; 51 total.Print(); 52 total = c1 - c2; 53 total.Print(); 54 return 0; 55 } 56
2)前置運算符重載("++"、"--")
1 類名 operator++() //前綴方式 2 類名 operator--() //前綴方式

1 #include <iostream> 2 #include <iomanip> 3 using namespace std; 4 5 class Point 6 { 7 private: 8 int x,y; 9 public: 10 Point(int i = 0, int j = 0); 11 Point operator++(); 12 Point operator--(); 13 void Print(); 14 15 }; 16 17 Point::Point(int i, int j) 18 { 19 x = i; 20 y = j; 21 } 22 23 void Point::Print() 24 { 25 cout << "(" << x << "," << y << ")" <<endl; 26 } 27 28 Point Point::operator--() 29 { 30 --x; 31 --y; 32 return *this; 33 } 34 Point Point::operator++() 35 { 36 ++x; 37 ++y; 38 return *this; 39 } 40 int main() 41 { 42 Point ob1(1, 2); 43 cout << "ob1:"; 44 ob1.Print(); 45 cout << "++ob1: "; 46 ++ob1; 47 cout << "ob1:"; 48 ob1.Print(); 49 cout << "--ob2:"; 50 ob1.Print(); 51 return 0; 52 }
3)后置運算符重載("++"、"--")
后綴與前綴的區別就在於(int),當然所實現的功能也有所不同
1 類名 operator ++(int) //后綴方式 2 類名 operator --(int) //后綴方式

1 #include <iostream> 2 using namespace std; 3 4 class Point 5 { 6 private: 7 int x,y; 8 public: 9 Point(int i = 0, int j = 0); 10 Point operator++(int); 11 Point operator--(int); 12 void Print(); 13 }; 14 15 Point::Point(int i, int j) 16 { 17 x = i; 18 y = j; 19 } 20 21 void Point::Print() 22 { 23 cout << "(" << x << "," << y << ")" <<endl; 24 } 25 26 Point Point::operator--(int) 27 { 28 Point temp = *this; 29 x--; 30 y--; 31 return temp; 32 } 33 Point Point::operator++(int) 34 { 35 Point temp = *this; 36 x++; 37 y++; 38 return temp; 39 } 40 41 int main() 42 { 43 Point ob1(1, 2),; 44 cout << "ob1:"; 45 ob1.Print(); 46 cout << "ob1++: "; 47 ob1++; 48 cout << "ob1--:"; 49 ob1--; 50 ob1.Print(); 51 return 0; 52 }
4)插入運算符重載(">>")、提取運算符重載("<<")

1 #include <iostream> 2 using namespace std; 3 4 class Distance 5 { 6 private: 7 int feet; // 0 到無窮 8 int inches; // 0 到 12 9 public: 10 Distance(){ 11 feet = 0; 12 inches = 0; 13 } 14 Distance(int f, int i){ 15 feet = f; 16 inches = i; 17 } 18 friend ostream &operator<<( ostream &output, const Distance &D ) 19 { 20 output << "F : " << D.feet << " I : " << D.inches; 21 return output; 22 } 23 24 friend istream &operator>>( istream &input, Distance &D ) 25 { 26 input >> D.feet >> D.inches; 27 return input; 28 } 29 }; 30 31 int main() 32 { 33 Distance D1(11, 10), D2(5, 11), D3; 34 cout << "Enter the value of object : " << endl; 35 cin >> D3; 36 cout << "First Distance : " << D1 << endl; 37 cout << "Second Distance :" << D2 << endl; 38 cout << "Third Distance :" << D3 << endl; 39 return 0; 40 }
五,重載運算符的方式
第一種就是把運算符重載函數作為類內成員函數,他可以通過this 指針自由的訪問本類的數據成員,因此可以少些一個參數
例:Complex operator +(Complex &);
第二種就是用普通函數重載(注意需要在類內聲明為友元函數)
例:friend Complex operator +(Complex &a1,Complex &a2);//聲明為友元函數
雙目運算符重載為友元函數時,由於友元函數不是該類的成員函數,因此在函數的形參列表里必須有兩個參數,不能省略
六,運算符重載的注意事項
1)並不是所有的運算符都可以重載。能夠重載的運算符包括:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
2)重載不能改變運算符的優先級和結合性。
3)重載不會改變運算符的用法
4)運算符重載函數不能有默認的參數,否則就改變了運算符操作數的個數
實驗例題
定義一個RMB類 Money,包含元、角、分三個數據成員,友元函數重載運算符‘+’(加)
和 ‘-’(減),實現貨幣的加減運算
例如:
請輸入元,角,分:
2 3 4
請輸入元,角,分:
3 7 3
和:6元0角7分
差:-1元3角9分
解析:利用運算符重載'+''-',在函數中實現對yuan,jiao,fen的運算的重載,再在主函數通過運算符實現。
代碼如下:

#include <iostream> using namespace std; class Money { private: int yuan, jiao, fen; bool flag; //標志位,0表示錢數為正,1表示錢數為負 -> 默認結果的錢數為正 public: Money(); Money(int fg, int y=0, int j=0, int f=0): yuan(y), jiao(j), fen(f), flag(fg){} friend Money operator+(Money a, Money b); friend Money operator-(Money a, Money b); void display(); }; Money::Money() { flag = 0; cout << "請輸入元、角 分:" <<endl; cin >> yuan >> jiao >> fen; } void Money::display() { if(flag==1) cout << '-'; cout << yuan << "元" << jiao << "角" << fen << "分" << endl; } //請用友元函數重載加/減,並要在類Money中聲明為友元 //TODO重載加 類外定義Money類的+重載運算 Money operator+(Money a, Money b) { Money temp(0); // 將錢全部轉化成分來計算 int money_a = a.yuan*100 + a.jiao*10 + a.fen*1; int money_b = b.yuan*100 + b.jiao*10 + b.fen*1; int res = money_a + money_b; // 因為是相加 故應該結果是正的 所以不用判斷符號 但是相減時 結果可能為負 就要判斷符號 temp.yuan = res/100; res = res % 100; temp.jiao = res/10; temp.fen = res % 10; // 返回結果對象 return temp; } //TODO重載減 類外定義Money類的-重載運算 Money operator-(Money a, Money b) { Money temp(0); // 將錢全部轉化成分來計算 int money_a = a.yuan*100 + a.jiao*10 + a.fen*1; int money_b = b.yuan*100 + b.jiao*10 + b.fen*1; int res = money_a - money_b; // 因為是相減時 結果可能為負 就要判斷符號 if(res < 0) { temp.flag = 1; res = -res; } temp.yuan = res/100; res = res % 100; temp.jiao = res/10; temp.fen = res % 10; // 返回結果對象 return temp; } int main() { Money m1, m2, m3(0), m4(0); //m3用來記錄和,m4用來記錄差 // + m3=m1+m2; cout<<"和:"; m3.display(); // - m4=m1-m2; cout<<"差:"; m4.display(); return 0; }