深刻解析C++編程中的運算符重載。本站提示廣大學習愛好者:(深刻解析C++編程中的運算符重載)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析C++編程中的運算符重載正文
C++中預界說的運算符的操尴尬刁難象只能是根本數據類型,現實上,關於許多用戶自界說類型,也須要有相似的運算操作。例如:
class complex { public: complex(double r=0.0,double I=0.0){real=r;imag=I;} void display(); private: double real; double imag; }; complex a(10,20),b(5,8);
“a+b”運算若何完成?這時候候我們須要本身編寫法式來講明“+”在感化於complex類對象時,該完成甚麼樣的功效,這就是運算符重載。運算符重載是對已有的運算符付與多重寄義,使統一個運算符感化於分歧類型的數據招致分歧類型的行動。
運算符重載的本質是函數重載。在完成進程中,起首把指定的運算表達式轉化為對運算符函數的挪用,運算對象轉化為運算符函數的實參,然後依據實參的類型來肯定須要挪用達標函數,這個進程愛編譯進程中完成。
1、 運算符重載的規矩
運算符重載規矩以下:
①、 C++中的運算符除多數幾個以外,全體可以重載,並且只能重載C++中已有的運算符。
②、 重載以後運算符的優先級和聯合性都不會轉變。
③、 運算符重載是針對新類型數據的現實須要,對原有運算符停止恰當的改革。普通來講,重載的功效應該與原有功效相相似,不克不及轉變原運算符的操尴尬刁難象個數,同時至多要有一個操尴尬刁難象是自界說類型。
不克不及重載的運算符只要五個,它們是:成員運算符“.”、指針運算符“*”、感化域運算符“::”、“sizeof”、前提運算符“?:”。
運算符重載情勢有兩種,重載為類的成員函數和重載為類的友元函數。
運算符重載為類的成員函數的普通語法情勢為:
函數類型 operator 運算符(形參表) { 函數體; }
運算符重載為類的友元函數的普通語法情勢為:
friend 函數類型 operator 運算符(形參表) { 函數體; }
個中,函數類型就是運算成果類型;operator是界說運算符重載函數的症結字;運算符是重載的運算符稱號。
當運算符重載為類的成員函數時,函數的參數個數比本來的操作個數要少一個;當重載為類的友元函數時,參數個數與原操作數個數雷同。緣由是重載為類的成員函數時,假如某個對象應用重載了的成員函數,本身的數據可以直接拜訪,就不須要再放在參數表中停止傳遞,少了的操作數就是該對象自己。而重載為友元函數時,友元函數對某個對象的數據停止操作,就必需經由過程該對象的稱號來停止,是以應用到的參數都要停止傳遞,操作數的個數就不會有變更。
運算符重載的重要長處就是許可轉變應用於體系外部的運算符的操作方法,以順應用戶自界說類型的相似運算。
2、 運算符重載為成員函數
關於雙目運算符B,假如要重載B為類的成員函數,使之可以或許完成表達式oprd1 B oprd2,個中oprd1為類A的對象,則應該把B重載為A類的成員函數,該函數只要一個形參,形參的類型是oprd2所屬的類型。經由重載後,表達式oprd1 B oprd2 就相當於函數挪用oprd1.operator B(oprd2).
關於前置單目運算符U,如“-”(負號)等,假如要重載U為類的成員函數,用來完成表達式U oprd,個中oprd為A類的對象,則U應該重載為A類的成員函數,函數沒無形參。經由重載以後,表達式U oprd相當於函數挪用oprd.operator U().
關於後置運算符“++”和“- -”,假如要將它們重載為類的成員函數,用來完成表達式oprd++或oprd--,個中oprd為A類的對象,那末運算符就應該重載為A類的成員函數,這時候函數要帶有一個整型形參。重載以後,表達式oprd++和oprd—就想當於函數挪用oprd.operator++(0)和oprd.operator—(0);
運算符重載就是付與已有的運算符多重寄義。經由過程從新界說運算符,使它可以或許用於特定類的對象履行特定的功效,這便加強了C++說話的擴大才能。
1. 運算符重載的感化:
運算符重載許可C/C++的運算符在用戶界說類型(類)上具有一個用戶界說的意義。重載的運算符是函數挪用的語法潤飾:
class Fred { public: // ... }; #if 0 // 沒有算符重載: Fred add(Fred, Fred); Fred mul(Fred, Fred); Fred f(Fred a, Fred b, Fred c) { return add(add(mul(a,b), mul(b,c)), mul(c,a)); // 哈哈,多好笑... } #else // 有算符重載: Fred operator+ (Fred, Fred); Fred operator* (Fred, Fred); Fred f(Fred a, Fred b, Fred c) { return a*b + b*c + c*a; } #endif
2. 可以用作重載的運算符:
算術運算符:+,-,*,/,%,++,--;
位操作運算符:&,|,~,^,<<,>>
邏輯運算符:!,&&,||;
比擬運算符:<,>,>=,<=,==,!=;
賦值運算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他運算符:[],(),->,,(逗號運算符),new,delete,new[],delete[],->*。
以下運算符不許可重載:
.,.*,::,?:
3. 運算符重載後,優先級和聯合性:
用戶重載新界說運算符,不轉變原運算符的優先級和聯合性。這就是說,對運算符重載不轉變運算符的優先級和聯合性,而且運算符重載後,也不轉變運算符的語法構造,即單目運算符只能重載為單目運算符,雙目運算符只能重載雙目運算符。
4. 編譯法式若何選用哪個運算符函數:
運算符重載現實是一個函數,所以運算符的重載現實上是函數的重載。編譯法式對運算符重載的選擇,遵守著函數重載的選擇准繩。當碰到不很顯著的運算時,編譯法式將去尋覓參數相婚配的運算符函數。
5. 重載運算符有哪些限制:
(1) 弗成臆造新的運算符。必需把重載運算符限制在C++說話中已有的運算符規模內的許可重載的運算符當中。
(2) 重載運算符保持4個“不克不及轉變”。
·不克不及轉變運算符操作數的個數;
·不克不及轉變運算符原本的優先級;
·不克不及轉變運算符原本的聯合性;
·不克不及轉變運算符原本的語法構造。
6. 運算符重載時必需遵守哪些准繩:
運算符重載可使法式加倍簡練,使表達式加倍直不雅,增長可讀性。然則,運算符重載應用不宜過量,不然會帶來必定的費事。
(1) 重載運算符寄義必需清晰。
(2) 重載運算符不克不及有二義性。
運算符重載函數的兩種情勢
運算符重載的函數普通地采取以下兩種情勢:成員函數情勢和友元函數情勢。這兩種情勢都可拜訪類中的公有成員。
3、例子
應用全局函數重載
#include <IOSTREAM.H> class A { public: A(int i):i(i){}; void print(){cout<<i<<endl;} friend A operator + (A &a, A &b);//聲明為友元 friend A operator ++(A &a, int); friend A& operator ++(A &a); friend A& operator +=(A &a, A &b); protected: int i; private: }; A operator + (A &a, A &b){//重載 a + b return A(a.i + b.i); } A operator ++(A &a, int){//重載 a++ return A(a.i++); } A& operator ++(A &a){//重載 ++a a.i++; return a; } A& operator +=(A &a, A &b){//重載 += a.i += b.i; return a; } void main(){ A a(5); A b(3); (a += b).print(); }
應用成員函數重載
#include <IOSTREAM.H> class A { public: A(int i):i(i){}; void print(){cout<<i<<endl;} A operator + (A &b); A& operator += (A &b); A operator ++(int); A& operator ++(); protected: int i; private: }; A A::operator + (A &b){//重載 + return A(i + b.i); } A& A::operator+= (A &b){ i += b.i; return *this; } A A::operator++ (int){//i++ return A(i++); } A& A::operator ++(){//++i i++; return *this; } void main(){ A a = 2; A b = 3; (++a).print(); (b++).print(); }