2013-02-12 157 views
4

特別是,前綴運算符的引用返回對我來說是有意義的 - 如果有人想對對象進行進一步的操作,這很有用。爲什麼後綴運算符設計爲按值返回?

但是,我無法理解爲什麼postfix運算符被設計爲按值返回。

它僅僅是一個約定,還是有一個很好的理由,爲什麼它是這樣設計的(就像一個按值返回對postfix沒有意義,但對前綴有意義)?

有人可以解釋一下嗎?

ANSWER

由於下面的答案,似乎後綴運算符不一定有(按標準)的值返回。

然而,由於後綴運算符的語義要求與標準要求(返回原始值,但遞增引用到原始值之後),結合:

操作重載是函數,因此所有的副作用必須在功能完成之前發生。

David Rodriguez下面,分叉值明確解釋似乎是語義需求的必然結果。在這種情況下,由於我們正在返回另一個值(不是原始參考,因爲它將通過函數的右大括號進行更改),因此返回值的其他值似乎是最有意義的。

+2

如何否則使用後會增加它嗎? – chris 2013-02-12 04:36:08

+0

從技術上講,如果你維護一個變量,告訴它在下次使用時增加它,你可以爲它自己的類工作。但是,對我來說似乎有點不對勁。 – chris 2013-02-12 04:38:53

+0

*「我認爲在大多數例子中,對象仍然存在。」* - 什麼對象?增加的對象?是的,通常是這樣。但是這是不相關的,因爲被遞增的對象不是postfix操作符返回的對象。我不確定你是否得到了這個。 – 2013-02-12 05:06:29

回答

8

後綴運算符是產生原始值,然後修改該對象的表達式。同時,操作符重載是函數,因此所有副作用都必須在函數完成之前發生。獲得所需語義的唯一方法是在應用更改之前複製對象的初始狀態。原來的狀態必須通過值被返回(如果返回的參考,所述表達的評估將產生的對象的狀態的函數完成後,並且因此將具有前綴運算符的語義,不postfix的那些)

+0

+1 *同時,操作符重載是函數,因此所有的副作用都必須在函數完成之前發生。*我認爲這是至關重要的約定(因此,不允許懶評估:語言/操作符語義將被打破)。 – kfmfe04 2013-02-12 05:16:33

5

這是慣例,因爲典型的實施修復後涉及創建一個臨時對象本地的函數,同時使用前綴運算符增加最初傳遞的對象,然後返回臨時對象。您無法返回對該本地對象的引用,因此需要按值返回。

您不能返回引用,因爲本地對象只保證在該函數的作用域內存在,並且任何對此作用域的訪問都將導致未定義的行爲。

+0

+1第一段看起來像一個重言式。然而,我認爲你的最後一段在正確的軌道上 - 是否有一個特定的例子(或C++規範中的某個例子),它顯示了執行後綴操作時獲得的對象。這絕對是通過價值回報而不是通過參考回報的原因。 – kfmfe04 2013-02-12 04:51:46

+1

@ kfmfe04:那你應該仔細閱讀。要更明確一點 - 'X運算符++(int){X x(* this); ++ *本; return x; }'/ +1 – 2013-02-12 05:17:45

+0

@ kfmfe04:我想你誤解了標準要求postfix應該按值返回。不,它不。該標準僅要求特定的可觀察行爲,實現可以以任何方式自由實現。在這種情況下,預期的行爲可以通過返回價值和大多數實現方便地實現,但我無法看到它無法理解的部分。 – 2013-02-12 05:27:04

2

下面的代碼在C和C++良好定義:

int i = 7; 
printf("%i\n", i++ + 2); 

這將打印9到控制檯,而i將8.保證。

後綴增加/減少修改i,但它們返回舊值i。用對象做這件事的唯一方法是將當前值保存在一個新值中,增加自己並返回保存的值。

+0

+1對於一個特定的例子 - 我認爲這與我正在尋找的非常接近 - 如果在後綴調用之後但在printf調用之前'''被破壞了,這個例子肯定會說明這個問題 – kfmfe04 2013-02-12 05:01:35

3

確定這是很好的理由。 後增量運算做以下的事情:

  1. 將變量和
  2. 返回其原來的值。

無法將引用返回到變量的「舊值」。它消失了。

+0

+1我認爲這可能是最好的解釋:沒有某種*懶惰或推遲的評估*,似乎沒有辦法通過引用來返回 – kfmfe04 2013-02-12 05:07:40

相關問題