C++重載
C++ 允許在同一作用域中的某個函數和運算符指定多個定義,分別稱為函數重載和運算符重載。本篇博客主要介紹C++中函數重載機制和運算符重載機制。
重載聲明是指一個與之前已經在該作用域內聲明過的函數或方法具有相同名稱的聲明,但是它們的參數列表和定義(實現)不相同(即參數個數或參數順序不同)。
當您調用一個重載函數或重載運算符時,編譯器通過把您所使用的參數類型與定義中的參數類型進行比較,決定選用最合適的定義。選擇最合適的重載函數或重載運算符的過程,稱為重載決策。
函數重載
在同一個作用域內,可以聲明幾個功能類似的同名函數,但是這些同名函數的形式參數(指參數的個數、類型或者順序)必須不同,不能僅通過返回類型的不同來重載函數。
示例:同名函數 print() 被用於輸出不同的數據類型:
#include <iostream> using namespace std; class printData { public: void print(int i) { cout << "Printing int: " << i << endl; } void print(double f) { cout << "Printing float: " << f << endl; }View Codevoid print(char* c) { cout << "Printing character: " << c << endl; } }; int main(void) { printData pd; pd.print(5); pd.print(500.263); pd.print("Hello C++"); return 0; }
運行結果為
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
運算符重載
您可以重定義或重載大部分 C++ 內置的運算符。這樣,您就能使用自定義類型的運算符。重載的運算符是帶有特殊名稱的函數,函數名是由關鍵字 operator 和其後要重載的運算符符號(如operator +
)構成的。與其他函數一樣,重載運算符有一個返回類型和一個參數列表。
基本格式 : 返回類型 operator 運算符 (參數列表)
可重載的運算符:
|+| -| * |\/ |% |^|
|–|–|–|–|–|–|
|& || |~ |! |, |=|
|< |>| <=| >=| ++| –|
|<<| >>| ==| !=| &&| || |
|+= |-= |/= |%= |^= |&=|
||=| *=| <<=| >>=| [] |()|
|-> |->* |new |new [] |delete |delete []|
不可重載的運算符:::
.*
.
?:
一元運算符重載
一元運算符只對一個數操作。++
,--
,-
(負號),!
(邏輯非)。
註意:對於自增,自減運算符的重載,需要區分前綴操作與後綴操作(後綴重載,參數為int,前綴重載無參數)。
#include <iostream> using namespace std; class Time { private: int hours; // 0 到 23 int minutes; // 0 到 59 public: // 所需的構造函數 Time(){ hours = 0; minutes = 0; } Time(int h, int m){ hours = h; minutes = m; } // 顯示時間的方法 void displayTime() { cout << "H: " << hours << " M:" << minutes <<endl; } // 重載前綴遞增運算符( ++ ) Time operator++ () { ++minutes; // 對象加 1 if(minutes >= 60) { ++hours; minutes -= 60; } return Time(hours, minutes); } // 重載後綴遞增運算符( ++ ) Time operator++( int ) { // 保存原始值 Time T(hours, minutes); // 對象加 1 ++minutes; if(minutes >= 60) { ++hours; minutes -= 60; } // 返回舊的原始值 return T; } }; int main() { Time T1(11, 59), T2(10,40); ++T1; // T1 加 1 T1.displayTime(); // 顯示 T1 ++T1; // T1 再加 1 T1.displayTime(); // 顯示 T1 T2++; // T2 加 1 T2.displayTime(); // 顯示 T2 T2++; // T2 再加 1 T2.displayTime(); // 顯示 T2 return 0; } /*運行結果為 H: 12 M:0 H: 12 M:1 H: 10 M:41 H: 10 M:42*/View Code
二元運算符重載
二元運算符需要兩個參數。我們平常使用的加運算符( + )、減運算符( - )、乘運算符( * )和除運算符( / )都屬於二元運算符。
示例(重載二元運算符+)
#include <iostream> using namespace std; class Box { double length; // 長度 double breadth; // 寬度 double height; // 高度 public: double getVolume(void) { return length * breadth * height; } void setLength( double len ) { length = len; } void setBreadth( double bre ) { breadth = bre; } void setHeight( double hei ) { height = hei; } Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } }; // 程序的主函數 int main( ) { Box Box1,Box2,Box3; double volume = 0.0; // 把體積存儲在該變量中 Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // Box1 的體積 volume = Box1.getVolume(); cout << "Volume of Box1 : " << volume <<endl; // Box2 的體積 volume = Box2.getVolume(); cout << "Volume of Box2 : " << volume <<endl; // 把兩個對象相加,得到 Box3 Box3 = Box1 + Box2; // Box3 的體積 volume = Box3.getVolume(); cout << "Volume of Box3 : " << volume <<endl; return 0; } /*運行結果為 Volume of Box1 : 210 Volume of Box2 : 1560 Volume of Box3 : 5400*/View Code
關系運算符重載
C++ 語言支持各種關系運算符( < 、 > 、 <= 、 >= 、 == 等等),它們可用於比較 C++ 內置的數據類型。我們可以重載任何一個關系運算符,重載後的關系運算符可用於比較類的對象。
示例:(重載 < 運算符)
#include <iostream> using namespace std; class Distance { private: int feet; // 0 到無窮 int inches; // 0 到 12 public: // 所需的構造函數 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } // 重載小於運算符( < ) bool operator <(const Distance& d) { if(feet < d.feet) { return true; } if(feet == d.feet && inches < d.inches) { return true; } return false; } }; int main() { Distance D1(11, 10), D2(5, 11); if( D1 < D2 ) { cout << "D1 is less than D2 " << endl; } else { cout << "D2 is less than D1 " << endl; } return 0; } //運行結果為: D2 is less than D1View Code
輸入輸出運算符重載
C++ 能夠使用流提取運算符 >>
和流插入運算符 <<
來輸入和輸出內置的數據類型。您可以重載流提取運算符和流插入運算符來操作對象等用戶自定義的數據類型。
註意:我們需要把運算符重載函數聲明為類的友元函數,這樣我們就能不用創建對象而直接調用函數。
示例:(重載提取運算符 >> 和插入運算符 <<)
#include <iostream> using namespace std; class Distance { private: int feet; // 0 到無窮 int inches; // 0 到 12 public: // 所需的構造函數 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } friend ostream &operator<<( ostream &output, const Distance &D ) { output << "F : " << D.feet << " I : " << D.inches; return output; } friend istream &operator>>( istream &input, Distance &D ) { input >> D.feet >> D.inches; return input; } }; int main() { Distance D1(11, 10), D2(5, 11), D3; cout << "Enter the value of object : " << endl; cin >> D3; cout << "First Distance : " << D1 << endl; cout << "Second Distance :" << D2 << endl; cout << "Third Distance :" << D3 << endl; return 0; } //運行結果 Enter the value of object : 12 10 First Distance : F : 11 I : 10 Second Distance :F : 5 I : 11 Third Distance :F : 12 I : 10*/View Code
賦值運算符重載
就像其他運算符一樣,您可以重載賦值運算符( = ),用於創建一個對象,比如拷貝構造函數。
示例:
#include <iostream> using namespace std; class Distance { private: int feet; // 0 到無窮 int inches; // 0 到 12 public: // 所需的構造函數 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } void operator=(const Distance &D ) { feet = D.feet; inches = D.inches; } // 顯示距離的方法 void displayDistance() { cout << "F: " << feet << " I:" << inches << endl; } }; int main() { Distance D1(11, 10), D2(5, 11); cout << "First Distance : "; D1.displayDistance(); cout << "Second Distance :"; D2.displayDistance(); // 使用賦值運算符 D1 = D2; cout << "First Distance :"; D1.displayDistance(); return 0; } /*示例程序執行結果: First Distance : F: 11 I:10 Second Distance :F: 5 I:11 First Distance :F: 5 I:11*/View Code
函數調用運算符()重載
函數調用運算符 () 可以被重載用於類的對象。當重載 () 時,您不是創造了一種新的調用函數的方式,相反地,這是創建一個可以傳遞任意數目參數的運算符函數。
示例:
#include <iostream> using namespace std; class Distance { private: int feet; // 0 到無窮 int inches; // 0 到 12 public: // 所需的構造函數 Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } // 重載函數調用運算符 Distance operator()(int a, int b, int c) { Distance D; // 進行隨機計算 D.feet = a + c + 10; D.inches = b + c + 100 ; return D; } // 顯示距離的方法 void displayDistance() { cout << "F: " << feet << " I:" << inches << endl; } }; int main() { Distance D1(11, 10), D2; cout << "First Distance : "; D1.displayDistance(); D2 = D1(10, 10, 10); // invoke operator() cout << "Second Distance :"; D2.displayDistance(); return 0; } /*示例程序執行結果: First Distance : F: 11 I:10 Second Distance :F: 30 I:120*/View Code
下標運算符[]重載
下標操作符 [] 通常用於訪問數組元素。重載該運算符用於增強操作 C++ 數組的功能。
示例:
#include <iostream> using namespace std; const int SIZE = 10; class safearay { private: int arr[SIZE]; public: safearay() { register int i; for(i = 0; i < SIZE; i++) { arr[i] = i; } } int& operator[](int i) { if( i > SIZE ) { cout << "索引超過最大值" ; // 返回第一個元素 return arr[0]; } return arr[i]; } }; int main() { safearay A; cout << "A[2] 的值為 : " << A[2] <<endl; cout << "A[5] 的值為 : " << A[5]<<endl; cout << "A[12] 的值為 : " << A[12]<<endl; return 0; } /*示例程序執行結果: A[2] 的值為 : 2 A[5] 的值為 : 5 A[12] 的值為 : 索引超過最大值0*/View Code
類成員訪問運算符->重載
類成員訪問運算符( -> )可以被重載,但它較為麻煩。它被定義用於為一個類賦予”指針”行為。運算符 -> 必須是一個成員函數。如果使用了 -> 運算符,返回類型必須是指針或者是類的對象。
運算符 -> 通常與指針引用運算符 * 結合使用,用於實現”智能指針”的功能。這些指針是行為與正常指針相似的對象,唯一不同的是,當您通過指針訪問對象時,它們會執行其他的任務。比如,當指針銷毀時,或者當指針指向另一個對象時,會自動刪除對象。
間接引用運算符 -> 可被定義為一個一元後綴運算符。也就是說,給出一個類:
#include <iostream> #include <vector> using namespace std; // 假設一個實際的類 class Obj { static int i, j; public: void f() const { cout << i++ << endl; } void g() const { cout << j++ << endl; } }; // 靜態成員定義 int Obj::i = 10; int Obj::j = 12; // 為上面的類實現一個容器 class ObjContainer { vector<Obj*> a; public: void add(Obj* obj) { a.push_back(obj); // 調用向量的標準方法 } friend class SmartPointer; }; // 實現智能指針,用於訪問類 Obj 的成員 class SmartPointer { ObjContainer oc; int index; public: SmartPointer(ObjContainer& objc) { oc = objc; index = 0; } // 返回值表示列表結束 bool operator++() // 前綴版本 { if(index >= oc.a.size()) return false; if(oc.a[++index] == 0) return false; return true; } bool operator++(int) // 後綴版本 { return operator++(); } // 重載運算符 -> Obj* operator->() const { if(!oc.a[index]) { cout << "Zero value"; return (Obj*)0; } return oc.a[index]; } }; int main() { const int sz = 10; Obj o[sz]; ObjContainer oc; for(int i = 0; i < sz; i++) { oc.add(&o[i]); } SmartPointer sp(oc); // 創建一個叠代器 do { sp->f(); // 智能指針調用 sp->g(); } while(sp++); return 0; } 示例程序執行結果: 10 12 11 13 12 14 13 15 14 16 15 17 16 18 17 19 18 20 19 21View Code
轉改於huqunxing。site
C++重載