關於c 成員運算子過載小總結

2021-10-05 13:53:28 字數 2886 閱讀 3439

在類內重構成員運算子的時候,會遇到乙個很怪的現象,就是在用物件使用重構的成員運算子,貌似會遞迴地訪問,但這種想法是有出入的,可能在過載成員運算子時出現問題。

1.呼叫過載後的成員運算子情況

我們在過載成員運算子的時候的要求

無引數必須是成員函式的形式過載

返回值型別僅能是過載了成員運算子的類或指向類(結構體)的指標

有沒有察覺到問題,返回值的型別為什麼只能是這兩種呢。這時候需要明確,我們何時呼叫原有的成員運算子,何時呼叫過載後的成員運算子。來用**說話。

//base 類

class

base

}//smartpoint 類

class

smartpoint

//注意這個display()

void

display()

base*

operator

->()

const

//返回指向base的指標型別

private:

base *_pbase;

}

在這樣的類定義中,兩個類均有display()函式,那如果執行下面的**,輸出結果是什麼呢

int

main()

是不是很簡單,這裡s1是物件,所以s1->採用了重構的成員運算子,s2是指標,所以採用未重構的成員運算子,結果自然很明顯:

class base

class smartpoint

其實我在查閱資料都不喜歡看**,只喜歡看總結,下來總結一下:

對於已經重構成員運算子的物件來說,會呼叫重構的成員運算子,若沒有重構,則報錯。如上面**中的s1->display()。

對於指標型別,則呼叫未重構的成員運算子。

那這時候估計就要想到了,前面重構成員運算子的返回型別是不是也是這樣的限制呢,首尾呼應啊,不過別急還沒到尾,接下來我們再看看,成員運算子不同的返回型別會有怎樣的情況。

2.區分過載的返回值

還記得我們最開始的**麼,我們提取成員運算子部分來看一下不同的返回值

最開始的**:

//smartpoint部分**,成員描述符的過載

class

smartpoint

}

另一種返回值:

//smartpoint部分**,成員描述符的過載

class

smartpoint

}

可以看到第二種過載後的成員運算子返回值型別是base類,不是乙個指標型別,那在我們其他不變的情況下,採用第二種情況會不會有錯誤呢。

int

main()

答案當然是會了,不然為什麼要這麼問呢

是不是感覺快到點子上了,別急,我們一下一下來。

第二種過載方式報錯

如果採用第二種過載方式:base operator->() const,為什麼會報錯呢。

當我們s1->display()時,會檢查此處s1是什麼型別,這裡它是乙個物件,過載了成員描述符的物件,所以就會將其解析為下面的形式

s1.

operator

->()

->

display()

;

對,這裡s1變成s1.operator->(),之後的完全沒有變,依然有乙個->成員描述符跟在後面,此時又會開始判斷,s1.operator->()是什麼型別,未過載成員描述符的物件,那從我們最開始的了解,此時會報錯。

第一種過載方式未報錯

那我們再來分析一下,最開始為什麼沒有報錯呢

還是一樣的展開:

s1.

operator

->()

->

display()

;

但這裡出現了不一樣的情況,s1.operator->()返回值是乙個指標,那這裡就相當於指標變數呼叫->訪問其成員,不需要使用過載後的成員運算子。

這裡就體現出,成員描述符的怪。

對於物件使用->,會一直呼叫其過載的成員描述符,直到返回值是乙個指標,那就意味著,如果有多個類,而且不停去呼叫過載後的成員描述符返回下乙個類,那最底層的類,其成員描述符的返回型別必須是乙個指標

若有錯誤非常感謝大家提出來,一起交流,非常感謝!!

下面分享乙個簡單的**,可以改變smartpoint類內的成員描述符重構函式的返回值,看看效果。

#include

using std::endl;

using std::cout;

class

root};

class

base

void

display()

root*

operator

->()

const

private

: root *_proot;};

class

smartpoint

void

display()

/* base* operator->() const */

/* */

base operator

->()

const

//可以改變返回型別,看看輸出結果是否是你的預期

private

: base *_pbase;};

intmain()

關於運算子過載 總結

1 運算子過載是為了對使用者自定義資料型別的資料的操作與內定義的資料型別的資料的操作形式一致。不能過載的5個運算子 成員指標訪問運算子 域運算子 sizeof長度運算子 條件運算子 成員訪問符。運算過載的三種方式 普通函式,友元函式,類成員函式。當過載為成員函式時,雙目運算子僅有乙個引數。對單目運算...

C 運算子過載函式之成員運算子過載函式

5.2.3 成員運算子過載函式 在c 中可以把運算子過載函式定義為某個類的成員函式,稱之為成員運算子過載函式。1.定義成員運算子過載函式的語法形式 1 在類的內部,定義成員運算子過載函式的格式如下 函式型別 operator 運算子 形參表 2 成員運算子過載函式也可以在類中宣告成員函式的原型,在類...

C 關於運算子過載

過載運算子的函式一般格式如下 函式型別 operator 運算子名稱 形參表列 例如,想將 用於complex類 複數 的加法運算,函式的原型可以是這樣的 complex operator complex c1,complex c2 在上面的一般格式中,operator是關鍵字,是專門用於定義過載運...