C++允許在同一個作用域中的某個函數和運算符指定多個定義,分別稱為函數重載和運算符重載。
重載聲明是指一個與之前已經在該作用域內聲明過的函數或方法具有相同名稱的聲明,但他們的參數列表和定義(實現)不相同。
當調用一個重載函數或重載運算符時,編譯器通過把函數所使用的參數類型和定義中的參數類型進行比較,決定選用最合適的定義。
選擇最合適的重載函數或重載運算符的過程,稱為重載決策。
?
C++函數重載
在同一個作用域內,可以聲明幾個功能類似的同名函數,但是這些同名函數的形式參數(參數個數,類型或者順序)必須不同,不能僅通過返回類型的不同來重載函數。
/*** overload.cpp ***/ #include<iostream> using namespace std;class printData {public:void print(int i){cout << "integer is : " << i << endl;}void print(double f){cout << "flota is : " << f << endl;}void print(char c[]){cout << "char is : " << c << endl;} };int main() {printData pd;pd.print(5);pd.print(300.1);char c[] = "hello C++";pd.print(c);return 0; }
運行結果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ vim overload.cpp
exbot@ubuntu:~/wangqinghe/C++/20190807$ g++ overload.cpp -o overload
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./overload
integer is : 5
flota is : 300.1
char is : hello C++
?
運算符重載:
我們可以重新定義或重在大部分C++內置的運算符。這樣就可以使用自定義的運算符了。
重載的運算符是帶有特殊名稱的函數,函數名是由關鍵字operator和其后要重載的運算符號構成。和其他函數一樣,重載運算符有一個返回類型和一個參數列表。
Box operator+(const Box&);
?
聲明加法運算符用于把兩個Box對象相加,返回最終的的Box對象。大多數重載運算符可被定義為普通的非成員函數或被定義為類成員函數。
如果我們定義上面的的函數為類的非成員函數,那么我們需要為每次操作傳遞兩個參數。如下所示:
Box operator+(const Box&, const Box&);
下面實例中,對象作為參數進行傳遞,對象的屬性使用this運算符進行訪問:
/***
overfun.cpp
***/
#include<iostream>
using namespace std;
?
class Box
{
??? public:
??????? Box(double l = 2.0,double b = 2.0,double h = 2.0)
??????? {
??????????? length = l;
??????????? breadth = b;
??????????? height = h;
??????? }
??????? double getVolume()
??????? {
??????????? return length*breadth*height;
??????? }
??????? 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(3.3,1.2,1.5);
??? Box box2(8.5,6.0,2.0);
??? Box box3;
??? double volume = 0.0;
?
??? volume = box1.getVolume();
??? cout << "Volume of box1 : " << volume << endl;
?
??? volume = box2.getVolume();
??? cout << "Volume of box2 : " << volume << endl;
?
??? box3 = box1 + box2;
?
??? volume = box3.getVolume();
??? cout << "Volume of box3 : " << volume << endl;
?
??? return 0;
}
運行結果:
exbot@ubuntu:~/wangqinghe/C++/20190808$ g++ overfun.cpp -o overfun
exbot@ubuntu:~/wangqinghe/C++/20190808$ ./overfun
Volume of box1 : 5.94
Volume of box2 : 102
Volume of box3 : 297.36
?
可重載運算符:
雙目算數運算符 | +,-,*,/,% |
關系運算符 | ==,!=,<,>,<= ,>= |
邏輯運算符 | || , &&? , ! |
單目運算符 | +(正),-(負),*(指針),&(取地址) |
自增自減運算符 | ++,-- |
位運算符 | | , &,~,^, ?<< , >> |
賦值運算符 | =,+=,-=,*=,/=,%=,&=,|=,^=, <<=,>>= |
空間申請與釋放 | new,delete,new[].delete[] |
其他運算符 | () (函數調用),->(成員訪問, ,(逗號),[] (下標) |
?
不可重載運算符列表:
. | 成員訪問運算符 |
.*,->* | 成員指針訪問運算符 |
:: | 域運算符 |
seizeof | 長度運算符 |
?: | 條件運算符 |
# | 預處理符號 |
Attention:
- 運算重載符不可以改變語法結構
- 運算重載符不可以改變操作數個數
- 運算重載付不可以改變優先級
- 運算重載符不可以改變結合性
?
類重載、覆蓋、重定義的區別:
重載指的是函數具有不同的參數列表,而函數名相同的函數。重載要求參數列表必須不同,比如參數的類型不同、參數的個數不同,參數的順序不同。因為重載要求參數列表必須不同。(同一類中)
覆蓋是存在類中,子類重寫從基類繼承過來的函數。被重寫的函數不能是static的。必須是virtual的。但函數名、返回值、參數列表都必須和基類相同(發生在基類和子類)。
重定義也叫做隱藏,子類重新定義父類中有相同名稱的非虛函數(參數列表可以不同)。(發生在子類和基類)。