C++ 函數重載
- ■ C++ 函數重載簡介
- ■ C++ 運算符重載
- ■ 一元運算符重載
- ■ 二元運算符重載 (+,-,*,/)
- ■ 關系運算符重載 ( < 、 > 、 <= 、 >= 、 == 等等)
- ■ 輸入/輸出運算符重載(運算符 >> 運算符 << )
- ■ 賦值運算符重載( = )
- ■ 函數調用運算符 () 重載
- ■ 下標運算符 [] 重載
- ■ 類成員訪問運算符 -> 重載
■ C++ 函數重載簡介
C++ 允許在同一作用域中的某個函數和運算符指定多個定義,分別稱為函數重載和運算符重載。
重載聲明是指一個與之前已經在該作用域內聲明過的函數具有相同名稱的聲明,但是它們的參數列表和定義(實現)不相同。
函數名相同,參數不同;
示例一:函數重載
#include <iostream>
using namespace std;
class printData
{public:void print(int i) {cout << "整數為: " << i << endl;}void print(double f) {cout << "浮點數為: " << f << endl;}void print(char c[]) {cout << "字符串為: " << c << endl;}
};int main(void)
{printData pd;// 輸出整數pd.print(5);// 輸出浮點數pd.print(500.263);// 輸出字符串char c[] = "Hello C++";pd.print(c); return 0;
}
會產生下列結果:
整數為: 5
浮點數為: 500.263
字符串為: Hello C++
■ C++ 運算符重載
您可以重定義或重載大部分 C++ 內置的運算符。
函數名是由關鍵字 operator 和其后要重載的運算符符號構成的。
重載運算符有一個返回類型和一個參數列表。
Box operator+(const Box&); //聲明加法運算符用于把兩個 Box 對象相加,返回最終的 Box 對象
■ 一元運算符重載
一元運算符只對一個操作數進行操作
示例一:
#include <iostream>
using namespace std;class Box
{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 對象相加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;}private:double length; // 長度double breadth; // 寬度double height; // 高度
};
// 程序的主函數
int main( )
{Box Box1; // 聲明 Box1,類型為 BoxBox Box2; // 聲明 Box2,類型為 BoxBox Box3; // 聲明 Box3,類型為 Boxdouble volume = 0.0; // 把體積存儲在該變量中// Box1 詳述Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0);// Box2 詳述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;// 把兩個對象相加,得到 Box3Box3 = 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
示例二:一元減運算符,即負號( - )
#include <iostream>
using namespace std;class Distance
{private:int feet; // 0 到無窮int inches; // 0 到 12public:// 所需的構造函數Distance(){feet = 0;inches = 0;}Distance(int f, int i){feet = f;inches = i;}// 顯示距離的方法void displayDistance(){cout << "F: " << feet << " I:" << inches <<endl;}// 重載負運算符( - )Distance operator- () {feet = -feet;inches = -inches;return Distance(feet, inches);}
};
int main()
{Distance D1(11, 10), D2(-5, 11);-D1; // 取相反數D1.displayDistance(); // 距離 D1-D2; // 取相反數D2.displayDistance(); // 距離 D2return 0;
}
它會產生下列結果:
F: -11 I:-10
F: 5 I:-11
■ 二元運算符重載 (+,-,*,/)
二元運算符需要兩個參數(+,-,*,/)
示例一:
// 重載 + 運算符,用于把兩個 Box 對象相加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;}
函數使用:
// 把兩個對象相加,得到 Box3
Box3 = Box1 + Box2;
■ 關系運算符重載 ( < 、 > 、 <= 、 >= 、 == 等等)
C++ 語言支持各種關系運算符( < 、 > 、 <= 、 >= 、 == 等等)
示例一:
#include <iostream>
using namespace std;class Distance
{private:int feet; // 0 到無窮int inches; // 0 到 12public:// 所需的構造函數Distance(){feet = 0;inches = 0;}Distance(int f, int i){feet = f;inches = i;}// 顯示距離的方法void displayDistance(){cout << "F: " << feet << " I:" << inches <<endl;}// 重載負運算符( - )Distance operator- () {feet = -feet;inches = -inches;return Distance(feet, inches);}// 重載小于運算符( < )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 D1
■ 輸入/輸出運算符重載(運算符 >> 運算符 << )
C++ 能夠使用流提取運算符 >> 和流插入運算符 << 來輸入和輸出內置的數據類型。
您可以重載流提取運算符和流插入運算符來操作對象等用戶自定義的數據類型。
示例一:
#include <iostream>
using namespace std;class Distance
{private:int feet; // 0 到無窮int inches; // 0 到 12public:// 所需的構造函數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;
}它會產生下列結果:
$./a.out
Enter the value of object :
70
10
First Distance : F : 11 I : 10
Second Distance :F : 5 I : 11
Third Distance :F : 70 I : 10
■ 賦值運算符重載( = )
用于創建一個對象,比如拷貝構造函數。
示例一:
#include <iostream>
using namespace std;
class Distance
{private:int feet; // 0 到無窮int inches; // 0 到 12public:// 所需的構造函數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
■ 函數調用運算符 () 重載
函數調用運算符 () 可以被重載用于類的對象。
當重載 () 時,您不是創造了一種新的調用函數的方式,相反地,這是創建一個可以傳遞任意數目參數的運算符函數。
示例一:
#include <iostream>
using namespace std;class Distance
{private:int feet; // 0 到無窮int inches; // 0 到 12public:// 所需的構造函數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
■ 下標運算符 [] 重載
下標操作符 [] 通常用于訪問數組元素。
重載該運算符用于增強操作 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 << "索引超過最大值" <<endl; // 返回第一個元素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;
}它會產生下列結果:
$ g++ -o test test.cpp
$ ./test
A[2] 的值為 : 2
A[5] 的值為 : 5
A[12] 的值為 : 索引超過最大值
0
■ 類成員訪問運算符 -> 重載
類成員訪問運算符( -> )可以被重載,但它較為麻煩。
它被定義用于為一個類賦予"指針"行為。運算符 -> 必須是一個成員函數。
如果使用了 -> 運算符,返回類型必須是指針或者是類的對象。
運算符 -> 通常與指針引用運算符 * 結合使用,用于實現"智能指
示例一:
#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() - 1) 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
21