2012-12-09 59 views
2

我看到這個C++代碼作爲一個更大的示例的一部分:算++:參考VS值返回和未使用的參數

Date &Date::operator++() 
{ 
    helpIncrement(); 
    return *this; 
} 

Date Date::operator++(int) 
{ 
    Date temp = *this; 
    helpIncrement(); 
    return temp; 
} 

首先如果Date temp = *this,然後我不明白爲什麼返回類型是對於這兩個功能的任何不同?一個返回*this,另一個返回temp,分配給*this

其次,爲什麼第二個函數的參數沒有變量名?

+1

另請參閱[此問題](http://stackoverflow.com/q/3846296/212858)和[此問題](http://stackoverflow.com/q/6375697/212858)...其實可能[大多數](http://stackoverflow.com/search?q=%5Bc%2B%2B%5D+increment+operator) – Useless

+0

@無用遺憾,沒有意識到它是具體到郵政增量 – user997112

+0

沒問題,鏈接僅供參考。我沒有投票結束重複,因爲你得到了有用的答案,使其成爲一個有用的參考。 – Useless

回答

6

第一個返回this指向的對象作爲參考。也就是說,返回的對象operator++被調用的對象。但是,當您執行Date temp = *this時,temp是從*this的值構建的副本。然後它被複製出功能。你從第二個函數中得到的是一個全新的對象。第二個問題的答案解釋了爲什麼這些功能有這種差異。

增量算子有兩種類型 - 一種是後增量(i++),另一種是前增量(++i)。爲了能夠逐個重載它們(儘管它們具有相同的名稱,即operator++),C++標準指定後增值運算符采用類型爲int的參數具有未指定的值。這很簡單,以便您可以爲操作員的每次使用重載該功能。既然你不太可能想要使用這個未指定的值,那麼你可以不要使用未命名的值。

現在,預增量運算符的預期行爲是增加對象並評估爲該對象。這就是爲什麼它在這種情況下返回一個參考。後增量的預期行爲是保留原始值的副本,增加對象然後返回原始值。因此,它返回temp副本。

1

這是一個很好的問題 - 它強調了一個相當愚蠢的設計選擇C++的設計者了:

  • 不帶參數的超載預增量; 未使用的過載int參數是後增量。
  • 這就是預增量版本可以返回引用的原因,而後增量必須在增加原始值之前複製原始文件。
  • int參數是由於單一原因而添加的 - 區分兩種重載;否則沒有意義,這就是爲什麼它的價值從未被使用。
+3

「愚蠢」是在旁觀者的眼中。你會如何做到這一點? –

+0

我必須說,答案同樣出色。 +1 – axiom

+0

@PeteBecker我腦海中有幾種選擇:一組關鍵字'preincrement' /'postincrement' /'predecrement'和'postdecrement'聽起來像是一個相當乾淨的選擇。 – dasblinkenlight

1

第一個運算符是預先遞增的:它遞增該值並返回結果。第二個是後增量:它增加值,並返回以前的值。在該代碼中,temp保存先前的值,helpIncrement()遞增該值,並返回先前的值(temp)。參數沒有名稱的原因是它沒有被使用。這有點破解;編譯器知道++my_value應翻譯成my_value.operator++(),而my_value++翻譯成my_value.operator++(1)。也就是說,缺少或存在一個整數參數決定調用哪個超載。

1
  1. 第一個函數在增加後返回對此的引用。第二個返回該副本,然後遞增。

  2. 第二個函數中未使用的參數區分++運算符的前綴(無參數)和後綴(單個int參數)版本。

這是一個基本主題,閱讀有關重載operator++。你可以從這裏開始:Operator overloading

1

首先,如果日期TEMP = *這一點,那麼我不明白爲什麼返回類型是這兩個功能有什麼不同?

我們來比較一下++int的情況。考慮

int i = 1; 
int j = i++; 

在此之後,j持有i舊值,但i本身遞增。所以i必須已事先向增加後

int i = 1; 
int j = ++i; 

ij複製,彷彿++int被定義爲

class int { // pseudocode 
    public: 
    int operator++(int) 
    { 
     int temp = *this; 
     *this += 1; 
     return temp; 
    } 
}; 

OTOH,具有相同的值,所以++必須已落實as

int &operator() 
{ 
    *this += 1; 
    return *this; 
} 

where change from intint&介紹方便性:不需要複製,並且在需要引用的情況下可以使用++i

其次,爲什麼那麼第二個函數參數沒有一個變量名?

因爲它永遠不會被使用。這個論點是作爲一個語法噱頭的,因此編譯器可以區分兩種類型的operator++(前後增量),但它沒有任何明確定義的值。賦予它一個名稱會觸發編譯器中的「未使用的標識符」選項,並啓用適當的警告。