2011-10-26 83 views
0

在C++中,無論我在網上看到後綴遞增運算符聲明的例子,它總是聲明爲C++後綴遞增運算符的常量返回類型

T& operator++(int); 

,我相信這是一個後綴的正確語法增量,不是嗎?

問題是,每當我聲明後綴增量時,我用const關鍵字聲明返回類型,以便它變成左值。

請參見示例代碼:

class AClass 
{ 
    int foo; 

public: 
    AClass(void) : foo(0) {}; 

    // Suffix increment operator 
    // Consider adding const to return type 
    /* const */ AClass operator++(int) 
    { 
     AClass cp(*this); 
     foo++; 
     return cp; 
    }; 

    // Prefix increment operator 
    AClass& operator++() 
    { 
     foo++; 
     return *this; 
    }; 
}; 

int main(int argc, const char* args[]) 
{ 
    /* This code would fail to compile. 
    int bar = 5; 
    (bar++)++; 
    */ 

    // Similarily, I would expect this to fail 
    // but it will succeed unless I use const return type. 
    AClass a; 
    (a++)++; 
} 

我從未有過這樣一個常量聲明的運營商的問題,我知道它已經救了我們的代碼從一個笨拙的同事做了一個錯誤。所以,我的問題是:

  1. 是否有任何缺點這樣的做法?這確實是一個好習慣嗎?
  2. 什麼是後綴運算符的真正正確的聲明(我的意思是標準)?
  3. 如果這不是標準的規定,但已經是一個很好的做法,它不應該成爲一個標準嗎?

非常感謝您的回答!

+0

你的前綴運算符應該返回一個引用:'AClass&operator ++()' – avakar

+0

II不能想到任何理由修改該函數的返回結果....我認爲你很好。 –

+0

謝謝,你是對的,已經糾正了這一點,但它並沒有改變這個問題。 – Andrew

回答

6

後綴增量返回一個臨時的,不是引用(這意味着你的第一個簽名是錯誤的):

T& operator++() // prefix 
{ 
    this->increment(); 
    return *this; 
} 

T operator++(int) // suffix 
{ 
    // Almost always, you'll have this code: 
    T tmp(*this); ++(*this); return tmp; 
} 

有些人喜歡爲const-資格後綴運算符的返回值,以避免編寫類似的蠢事

(a++).modify_me(); 

不修改a(它適用modify_me到一個臨時對象)。與

(++a).modify_me(); 

它增加a,然後修改它。

個人而言,我不認爲這是必要的(因爲您可能對modify_me的副作用感興趣)。而且,在C++ 11中,您可能希望將所述臨時值綁定到(非const)右值引用。 Const限定後綴運算符的返回類型會禁用這種可能性。

+2

+1:const rvalues不好。 – Puppy

+0

@DeadMG:完美地說。例如,看到另外一些很好的書籍,例如Numerical Recipes,它系統性地將r值參數限定爲函數本質上是沒有道理的。 –

+0

@Alexandre:原因是提問者說,允許內置運算符允許的表達式,並禁止它們禁止的表達式。這不是「沒有理由」,只是有更好的理由去做相反的事情(在C++ 11中移動語義,但即使在C++ 03中也存在互換優化)。 –

1

我相信這是一個後綴增量的正確語法,是不是 呢?

如果通過「正確」,你的意思是「普遍的做法」,那麼沒有。如果你試圖創建與整數後綴運算符一致的行爲,那麼它應該按值返回。

const T operator++(int); 

這是因爲它會進行復制,然後遞增,然後返回副本。由於副本是本地的,你絕對不想通過引用返回它。

您可以帶走或離開的常量,但通過價值而不是參考的回報是必不可少的。