1、什麼是操做符重載ios
操做符重載能夠分爲兩部分:「操做符」和「重載」。說到重載想必都不陌生了吧,這是一種編譯時多態,重載實際上能夠分爲函數重載和操做符重載。運算符重載和函數重載的不一樣之處在於操做符重載重載的必定是操做符。咱們不妨先直觀的看一下所謂的操做符重載:函數
#include <iostream> using namespace std; int main() { int a = 2 , b = 3; float c = 2.1f , d = 1.2f; cout<<"a + b = "<<a+b<<endl; cout<<"c + d = "<<c+d<<endl; return 0; }
咱們看到操做符「+」完成float和int兩 種類型的加法計算,這就是操做符重載了。這些內置類型的操做符重載已經實現過了,可是若是如今咱們本身寫過的類也要實現實現相似的加法運算,怎麼辦呢?? 好比如今如今有這樣一個點類point,要實現兩個點的相加,結果是橫縱座標都要相加,這時候就須要咱們本身寫一個操做符重載函數了。this
#include <iostream> using namespace std; class point { double x; double y; public: double get_x() { return x; } double get_y() { return y; } point(double X = 0.0 , double Y = 0.0):x(X),y(Y){}; point operator +(point p); }; //重載操做符「+」 point point::operator +(point p) { double x = this->x + p.x; double y = this->y + p.y; point tmp_p(x,y); return tmp_p; } int main() { point p1(1.2,3.1); point p2(1.1,3.2); point p3 = p1+p2; cout<<p3.get_x()<<" "<<p3.get_y()<<endl; return 0; }
2、實現操做符重載的兩種方式spa
操做符重載的實現方式有兩種,即經過「友元函數」或者「類成員函數」。指針
1.友元函數重載操做符的格式:code
class 類名 { friend 返回類型 operator 操做符(形參表); }; //類外定義格式: 返回類型 operator操做符(參數表) { //函數體 }
2.類成員函數實現操做符重載的格式:對象
class 類名 { public: 返回類型 operator 操做符(形參表); }; //類外定義格式 返回類型 類名::operator 操做符(形參表) { //函數體 }
這樣說吧,仍是不足以比較這兩種實現方式的區別,咱們分別用兩種實現方式寫point類的」+「和」-「的重載。代碼以下:作用域
#include <iostream> using std::endl; using std::cout; class point { double x; double y; public: double get_x() { return x; } double get_y() { return y; } point(double X = 0.0 , double Y = 0.0):x(X),y(Y){}; friend point operator -(point p1,point p2); point operator +(point p); }; //重載操做符「-」 point operator -(point p1,point p2) { double x = p1.get_x() - p2.get_x(); double y = p1.get_y() - p2.get_y(); point p3(x,y); return p3; } //重載操做符「+」 point point::operator +(point p) { double x = this->x + p.x; double y = this->y + p.y; point tmp_p(x,y); return tmp_p; } int main() { point p1(1.2,3.2); point p2(1.1,3.1); point p3 = p1+p2; point p4 = operator-(p1,p2); cout<<p3.get_x()<<" "<<p3.get_y()<<endl; cout<<p4.get_x()<<" "<<p4.get_y()<<endl; return 0; }
這裏不知道你們看到沒有,利用友元函數重載二元操做符」-「時,形式參數是兩個, 而利用類成員函數時,形式參數卻只有一個。這時由於類成員函數中存在this指針,這至關於一個參數,因此類成員實現操做符重載須要的形式參數比原來少一 個,這好比:利用類成員函數實現一元操做符」-「,就不須要參數了。也正是由於這個緣由,友元函數實現的操做符重載是有限制的,好比:[] ,(),->和 =不能利用友元函數實現運算符的重載。開發
在實際開發過程當中,單目運算符建議重載爲成員函數,而雙目運算符建議 重載爲友元函數。一般下雙目運算符重載爲友元函數比重載爲成員函數更方便,可是有時雙目運算符必須重載爲成員函數,例如賦值運算符=。還有若是須要修改對 象內部的狀態,通常能夠選擇利用類成員函數進行修改。get
3、運算符重載的原則
這樣一看,運算符重載仍是蠻簡單的嘛,實際上運算符重載也是要遵循一些原則的:
1.C++中只能對已有的C++運算符進行重載,不容許用戶本身定義新的運算符。
2.C++中絕大部分的運算符可重載,除了成員訪問運算符.,做用域運算符::,長度運算符sizeof以及條件運算符?:。
3.運算符重載後不能改變運算符的操做對象(操做數)的個數。如:"+"是實現兩個操做數的運算符,重載後仍然爲雙目運算符。
4.重載不能改變運算符原有的優先級和原有的結合性。
6.運算符重載不能所有是C++中預約義的基本數據,這樣作的目的是爲了防止用戶修改用於基本類型數據的運算符性質。
4、爲何要進行運算符重載
關於運算符重載要遵循這麼多原則,那麼爲何還要進行運算符重載呢?爲何我不是 寫一個add()函數,代替operator +()呢??我的感受C++中之因此要支持運算符的重載是爲了與內置數據類型統一操做,好比:c = a + b 和 c = add(a,b),這看起來哪一個更直觀一點呢,顯然是前者了。同時,咱們但願操做咱們本身定義的數據類型能像操做int和double這些內置數據類型一 樣方便。可能舉這個加法的例子有點很差,如今加入重載的運算符是[],<<,^,|等呢?這時咱們要用什麼成員函數代替呢??代替以後又是一 種什麼效果呢?會一眼就看出來這個函數要幹什麼嗎??