2014-08-29 59 views
4

我正在學習如何重載「 - >」和文檔說: 「operator->再次調用它遞歸的值,直到操作符 - >到達,返回一個普通指針,然後,內建語義應用於該指針。「重載「 - >」(成員訪問)遞歸

雖然很清楚文檔說的是什麼,但基本上一個類的重載「 - >」可以使用自己的「特殊指針」,本身有一個重載的「 - >」,可以給一個「特殊指針」等等。直到找到「普通指針」爲止,我找不到真正使用它的例子(除非它用於查找鏈表的最後一個元素)。

有人可以解釋幕後的情況是什麼(因爲這種可能性沒有提供「普通指針」 - 所以我不認爲有任何理由提供它「特殊指針」)。

真實世界使用的一個例子也可以提供幫助,因爲可能我錯過了一個應用該行爲的模型。

在另一方面可能需要避免這種行爲,它怎麼能做到?

+0

可否請你定義「普通指針」,我擡頭一看什麼shared_ptr的「特殊指針」 – CoffeeandCode 2014-08-29 16:49:43

+0

,但如果是遞歸? – 2014-08-29 16:50:10

+1

「普通指針」是C++的「普通指針」。 – 2014-08-29 16:50:54

回答

2

我找不到一個真正使用它的例子(除非它用於查找鏈表的最後一個元素)。

我認爲你誤解了它的功能。它不用於取消引用列表元素並保持取消引用下一個元素。每次打電話給operator->時,你會得到一個不同的類型,問題是如果第二種類型也有operator->它會被調用,這可能會再次返回一個不同的類型。想象一下,它是像x->->->ix->next->next->next是否有幫助

的現實世界中使用的例子可以幫助也一樣,也許我缺少一個模型,其中應用的行爲。

它可以用於Execute Around Pointer模式。

在另一方面,可能需要避免這種行爲,該怎麼辦?

電話運營商明確:

auto x = p.operator->(); 
7

那麼,->運營商在評價者的特殊情況下工作。

可以稱之爲僞二元運算符。根據其自然語法pointer->member它需要兩個操作數:左側的正常運行時操作數和右側的相當「奇怪」的成員名稱操作數。第二操作數的「奇異性」源於C++語言沒有用於表示這些操作數的用戶可訪問概念的事實。語言中沒有任何內容會將成員名稱表示爲操作數。沒有辦法通過代碼將用戶名稱「傳遞」給用戶定義的實現。成員名稱是一個編譯時間實體,在這方面與常量表達式類似,但C++中沒有常量表達式可以指定成員。 (有指向成員的表達式,但不是成員本身)。

這在指定過載運算符的行爲時會產生相當明顯的困難:我們如何將->(即成員名稱)右側指定的內容連接到用戶編寫的代碼?不可能直接做到這一點。這種情況的唯一出路是間接地做到這一點:強制用戶將過載的運營商的用戶定義的功能引導到一些現有的運營商的功能。內置的操作符可以通過其核心語言功能自然處理成員名稱。

在這種特殊情況下,我們只有兩個候選人將超載->的功能引導至:內置->和內置.。內在的->被選爲這個角色是合乎邏輯的。這產生了一個有趣的副作用:編寫「鏈式」(遞歸)序列的重載運算符(由編譯器隱式展開)甚至是無限遞歸序列(這是不合格的)的可能性。

非正式地說,每當你使用智能指針時,你都會真實地使用這些超載運算符的「遞歸」屬性。如果你有一個智能指針sptr指向一個帶有成員member的類對象,那麼成員訪問語法保持完全自然,例如, sptr->member。您不必將其作爲sptr->->membersptr->.member來執行,具體原因是超載->的隱式「遞歸」屬性。

注意,當您使用操作語法調用重載->操作,即object->member語法這個遞歸行爲僅適用。但是,您也可以使用常規成員函數調用語法來調用您的超載->,例如object.operator ->()。在這種情況下,該調用是作爲普通函數調用進行的,並且不會發生->的遞歸應用。這是避免遞歸行爲的唯一方法。如果要實現重載->操作返回類型不支持->運營商的進一步應用程序(例如,你可以定義一個重載->返回int),那麼object.operator ->()將調用您的重載實現的唯一途徑。任何使用object->member語法的嘗試都是不合格的。

+0

有指向成員的指針,所以不知何故程序員也可以訪問「成員」概念。 – 2014-08-29 16:53:54

+0

但問題是關於遞歸! – 2014-08-29 16:54:24

+2

@GeorgeKourtis,但是當右操作數是一個指向成員的指針時,你必須聲明'x - > * pmf'不是'x-> name',所以它不能通過'operator->'來訪問 – 2014-08-29 16:54:53