過載運算子是c++語言的優點之一,對已有的運算子進行過載,賦予其另一種功能,以適應不同的資料型別。運算子過載的宣告方式是關鍵字operator+相關運算的符號。
運算子的過載事實上是在定義函式:
《返回型別說明》 operator《運算子符號》(引數列表)
運算子的過載要遵循以下規則:
1.除了類屬關係運算子 』 . 『, 成員指標運算子 』 * 『, 作用域運算子 『::』 , sizeof運算子,以及三目運算子以外,c++中所有的運算子都可以被過載。
2.過載運算子限制在c++語言中已有的運算子範圍之內的允許過載的運算子之中,不能建立新的運算子。
3.運算子過載的實質是函式的過載,因此編譯過程中對運算子過載的選擇,遵循函式過載的選擇原則。
4.過載之後的運算子不能改變運算子的優先順序和結核性,也不能改變運算子的運算元和語法。
5.運算子過載不能改變運算子內部型別物件的含義。它只能和使用者自定義型別的物件一起使用,或者用於使用者自定義型別的物件和內部型別的物件混合使用。
6.運算子過載是針對新型別資料的實際需要對原有的運算子進行適當的改造,過載的功能應當與原有的功能相似,避免沒有目的地使用過載運算子。
運算子的過載一般有兩種形式,過載為類的成員和過載為類的非成員函式。非成員函式通常是友元函式(比如過載輸出流)
當運算子過載為類的成員函式時,函式的引數個數比原來的運算元少乙個(*this指標隱式存在,成員函式用this指標隱式地訪問了類的乙個物件,它充當了運算子的最左邊的運算元)
當運算子過載為類的友元函式時,由於沒有隱含的this指標,因此運算元沒有變化,所有運算元都必須通過函式的形參進行傳遞,函式的引數與運算元目一一對應。
下面給出過載各類運算子的例項。
#include
using
namespace
std;
class int
中 {}
~int()
private:
int m_i;
};
我們構造了乙個類int,類裡有int型的m_i。我們通過過載運算子要達到對int物件的操作要和對int整形操作一樣。
我們通過**分別實現 + - * / % , += -= *= /= , int++, ++int, -(取負數), >> <<, && || , & | , new delete,以及過載輸出流。
#include
using
namespace
std;
class int
~int()
public:
int operator+(const int &i);
void
operator+=(const int &i);
int operator%(const int &i);
void
operator%=(const int &i);
int operator++(int); //int++
int operator++(); //++int
int operator-();
bool
operator>=(const int &i);
int operator>>(int &i);
int operator&(const int &i);
intoperator|(const int &i);
bool
operator&&(const int &i);
bool
operator||(const int &i);
void *operator
new(size_t sz);
void
operator
delete(void *p);
private:
int m_i;
};
「+ - * /」相似,以+為例:
int& int::operator+(const
int &i)
在類外實現函式要加上類的作用域(int::)防止二異性。在引數列表中隱藏包含了this指標,所以引數列表可以還原為(*this, const int &i)。this指標是指向當前物件的意思,在這個**中,operator前面的物件就是this指標所指,後面的物件就是傳進來的引數 i 。兩個int型別的資料相加,實際定義為int類內部的m_i相加並返回int型的資料 : i.m_i + m_i 。
int main()
如果這樣直接輸出的話,程式會報錯:don`t define < < . 我們還要對int型別如何輸出進行定義。
class int; //寫在class之前,要宣告為友元前要先定義class
ostream& operator
<<(ostream &out, const int &i);//定義過載輸出《的函式,注意這裡可沒有*this
friend ostream& operator
<< (ostream &out, const int &i);//在class內部開頭,宣告為友元,這樣就可以呼叫私有成員m_i了。
ostream& operator
<<(ostream &out, const int &i)//在class外部實現《的過載,輸出i.m_i
這樣我們就可以編譯通過了,輸出結果是: 3 ,對自己定義的int類也能進行加法運算啦。
tips以前有這麼一道面試題,問可不可以將 輸出流<< 當做類的成員函式進行過載?
答案是可以的,但事實上沒有人這麼做。因為如果作為成員函式就會引入this指標,輸出時要靠物件去驅動函式(等同於+ - * /),那麼輸出《的操作就會由 cout << a ; 變為 a cout ; .這樣的方式與我們平常的習慣不同,違反了過載的原則。
我們再來看一下取餘%運算子的過載:
int& int::operator%(const
int &i)
和+很類似,在內部實際進行的是m_i之間的運算。
tips大家有沒有注意到宣告時int後面的 &,這個符號是什麼作用呢?在常規的函式中,當返回乙個值時函式的生命也就終結了,它會被析構函式析構掉,那麼這個值是怎麼儲存的呢?實際上函式提前會將這個值存入某個不知名記憶體中,當另個程式需要返回值時,它來傳遞返回值,傳遞完在被釋放掉。程式執行過程中申請乙個空間在釋放掉,無疑是耗費時間的。而&得作用就是延長返回值的生命,直到返回值被接受,這樣我們就避免了多餘的申請釋放空間所花費的時間,提高了程式的運算速度。
我們來看看+= 這類運算子的過載。
void int::operator+=(const int &i)
過載運算子時要注意運算子的性質,a = a + b; 和 a += b; 在過載運算子時是不同的,+ 的過載需要返回值,但 += 不需要返回值,因為是直接對this指標進行操作的。
下來我們再來看看比較複雜的兩個 int++ 和 ++int。
int int::operator++() //++a
++a先加再計算,this的m_i++,在返回this指標。
int& int::operator++(int ) //a++
a++由於先運算在++,所以我們得定義int型的臨時類,將this指標的m_i++,返回臨時類temp。
a++在這裡的引數要求有乙個整型int,++a不需要,這是編譯器規定的,用於區分++運算子是前++還是後++。
當bool型別的運算子過載時,比如》 ,< ,>= , <=, 要符合運算子的性質。
bool int::operator&&(const int &i)
else
}bool int::operator||(const int &i)
else
}
在來看看new,delect運算子的過載。
void* int::operator
new(size_t sz)
void int::operator
delete(void *p)
再補充一點,當定義乙個類後,如何用類物件直接給整型賦值?
classa;
int a = a; //怎麼賦值?
技巧是過載int!
operator
int()const
運算子過載的所有形式都已經介紹完畢,將運算子作為函式一樣的呼叫,使得我們運用型別的語法時更加靈活。
過載運算子需要掌握的的知識點:
1.運算子過載的實質。
2.學會處理過載時的引數。
3.學會分清不同運算子過載時的返回值。
4.搞清運算子時成員函式還是友元函式,和兩者的區別。
過載運算子
題目描述 定義乙個矩形類,資料成員包括左下角和右上角座標,定義的成員函式包括必要的建構函式 輸入座標的函式,實現矩形加法,以及計算並輸出矩形面積的函式。要求使用提示中給出的測試函式並不得改動。兩個矩形相加的規則是 決定矩形的對應座標分別相加,如 左下角 1,2 右上角 3,4 的矩形,與 左下角 2...
過載運算子
include include using namespace std class test test const int a v a test const test t1 v t1.v 以下過載小於號 比較兩個物件的大小 bool operator const test t1 const 比較物件...
過載運算子
1.當乙個過載的運算子是成員函式時,this繫結到左側運算物件。成員運算子函式的引數比運算物件的數量少乙個。非成員函式呼叫等價於 data1 data2 普通表示式 operator data1,data2 等價的函式呼叫成員函式呼叫等價於 data1 data2 普通表示式 data1.opera...