C 學習之 運算子過載

2021-09-19 06:37:58 字數 3832 閱讀 1140

要過載運算子,需要使用被稱為運算子函式的特殊函式形式,運算子函式的格式如下:

operatorop(atgument-list)

例如,operator+()過載+運算子,operator*()過載*運算子。op必須是有效的c++運算子,不能虛構乙個新的運算子

乙個運算子過載示例

time time::operator+(const time & t) const //const表明函式不會更改呼叫物件

這兩種表示方法等價:

total = coding.operator+(fixing);//函式呼叫

total = coding + fixing;//運算子過載

這兩種表示法都將呼叫operat+()方法,注意:在運算子表示法中,運算子左側的物件(這裡為coding)是呼叫物件(隱式引數),運算子右邊的物件(這裡是fixing)是作為引數被傳遞的物件(顯式引數)

編譯器將根據運算元的型別來確定如何做:

int a,b,c;

time a,b,c;

c = a + b; //使用int的+號

c = a + b; //用運算子過載呼叫

可以將兩個以上的物件相加,如:

t4 = t1 + t2 + t3;
由於+是從左向右結合的運算子,因此上述語句首先被轉換成下面這樣:

t4 = t1.operator+(t2 + t3);
然後,函式引數本身被轉換成乙個函式呼叫,結果如下:

t4 = t1.operator+(t2.operator+(t3));
函式呼叫t2.operator+(t3)返回乙個time物件,後者是t2和t3的和,然而,該物件稱為函式呼叫t1.operator+()的引數,該呼叫返回t1與t2和t3之和的time物件的和

過載限制

過載的運算子不必是成員函式,但必須至少有乙個運算元是使用者自定義的型別下面詳細介紹c++對使用者定義的運算子過載的限制

1、過載後的運算子必須至少有乙個運算元是使用者定義的型別,這將防止使用者為標準型別過載運算子,不能將減法運算子(-)過載為計算兩個double值的和,而不是它們的差

2、使用運算子時不能違反運算子原來的句法規則,例如,不能將求模運算子(%)過載成使用乙個運算元,同樣,不能修改運算子的優先順序

3、不能建立新的運算子,例如,不能定義operator**()函式來求冪

4、不能過載下面的運算子:

5、大多數運算子可以通過成員或非成員函式進行過載,但下面的運算子只能通過成員函式進行過載

友元有3種:

通過讓函式成為類的友元,可以賦予該函式與類的成員函式相同的訪問許可權

在前面的示例中,加法運算子結合兩個time值,而乘法運算子將乙個time值與乙個double值結合在一起,這限制了運算子的使用方式,記住,左側的運算元是呼叫物件,也就是說,下面的語句:

a = b * 2.75;
將被轉換為下面的成員函式呼叫:

a = b.operator*(2.75);
但下面的語句有如何呢

a = 2.75 * b;
從概念上說,2.75 * b應與b * 2.75相同,但第乙個表示式不對應與成員函式,因為2.75不是time型別物件,記住,左側的運算元應是呼叫物件

解決這個難題的一種方式是,告知每個人,只能按b * 2.75這種格式編寫,不能寫成2.75 * b

然而,還有另一種解決方式–非成員函式,記住,大多數運算子都可以通過成員或非成員函式來過載,非成員函式不是由物件呼叫的,它使用的所有值(包括物件)都是顯式引數,這樣編譯器能將下面的表示式:

a = 2.75 * b;
與下面的函式呼叫匹配

a = operator*(2.75, b);
該函式的原型如下:

time operator*(double m, const time & t);
對於非成員過載運算子函式來說,運算子表示式左邊的運算元對應於運算子函式的第乙個引數,運算子表示式右邊的運算元對應於運算子函式的第二個引數

但引發了乙個問題:非成員函式不能直接訪問類的私有資料,至少常規非成員函式不能訪問,然而,有一類特殊的非成員函式可以訪問類的私有成員,它們被稱為友元函式

建立友元

建立友元函式的第一步是將其原型放在類宣告中,並在原型宣告前面加上關鍵字friend:

friend time operator*(double m, const time & t);
該原型意味著兩點:

第二步是編寫函式定義,不要在函式定義中加關鍵字friend,定義如下:

time operator*(double m, const time & t)

有了上述宣告和定義後,下面的語句:

a = 2.75 * b;
將轉換為如下語句,從而呼叫剛才定義的非成員友元函式

a = operator*(2.75, b);
實際上,下面的方式對定義進行修改,可以將這個友元函式編寫為非友元函式:

time operator*(double m, const time & t)

原來的版本顯式地訪問t.minutes和t.hours,所以它必須是友元,這個版本將time物件t作為乙個整體使用,讓成員函式來處理私有值,因此不必是友元

常用的友元:過載《運算子

假設trip是乙個time物件,為顯式time的值,前面使用的是show(),然而,如果可以像下面這樣操作將更好:

cout《之所以可以這樣做,是因為《是可被過載的c++運算子之一

1、《的第一種過載版本

要使time類知道使用cout,必須使用友元函式,因為下面這樣的語句使用兩個物件:

cout《如果使用乙個time成員函式來過載<<,time物件將是第乙個運算元,就像使用成員函式過載*運算子那樣

trip《這樣會令人迷惑,但通過使用友元函式,可以像下面那樣過載運算子:

void operator<<(ostream & os, const time & t)

運算元的順序非常重要,下面的語句:

diff = v1 - v2;

將被轉換為下面的成員函式呼叫:

diff = v1.operator-(v2);
這意味著將從隱式向量引數減去以顯式引數傳遞的的向量,所以應使用x-b.x而不是b.x-x

接下來,來看一元負號運算子,它只使用乙個運算元,將這個運算子用於數字(如-x)時,將改變它的符號

下面是過載負號的原型和定義:

vector operator-() const;

vector vector::operator-() const

現在,operator-()有兩種不同的定義,這是可行的,因為它們的特徵標不同,可以定義-運算子的一元和二元版本,因為c++提供了該運算子的一元和二元版本,對於只有二元形式的運算子(如除法運算子),只能將其過載為二元運算子

因為運算子過載是通過函式來實現的,所以只要運算子函式的特徵標不同,使用的運算子數量與相應的內建c++運算子相同,就可以多次過載同乙個運算子

c 學習之運算子過載

今天這篇部落格 寫的是運算子的過載,這裡單純的寫了 號的運算子的過載,主要就是為了在以後需要的時候能夠找到對應的資料,還有就是通過作用域解析運算子來返回我們通過返回乙個物件 這裡有些運算子是不能載入的,有些運算子是只能通過成員函式來載入,以下截圖來自c primer plus 這段 寫的是乙個複數的...

C 運算子過載之過載單目運算子

單目運算子只有乙個運算元,但是其過載方法類似於雙目運算子,在這裡以過載單目運算子 為例,介紹單目運算子的過載 注意 和 運算子有兩種使用方式,前置自增運算子和後置自增運算子,它們的作用是不一樣的,為了區分他們,c 約定,在自增 自減 運算子過載函式中,增加乙個int型別的形參,就是後置自增 自減 運...

C 之「運算子過載」

c 可以過載的運算子有 1.前置 和後置 2.前置 與後置 3.運算子 4.運算子 5.流提取與流插入 運算子 特別注意 要對類的物件使用運算子,不能過載的運算子 逗號運算子 includeusing namespace std class operate operate operate int x...