2012-02-26 197 views
0

http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/執行前綴操作符++

類聲明

class Digit 
{ 
private: 
    int m_nDigit; 
public: 
    Digit(int nDigit=0) 
    { 
     m_nDigit = nDigit; 
    } 

    Digit& operator++(); 
    Digit& operator--(); 

    int GetDigit() const { return m_nDigit; } 
}; 

其實施operator++

Digit& Digit::operator++() 
{ 
    // If our number is already at 9, wrap around to 0 
    if (m_nDigit == 9) 
     m_nDigit = 0; 
    // otherwise just increment to next number 
    else 
     ++m_nDigit; 

    return *this; 
} 

我的備用實施operator++

Digit& Digit::operator++() 
{ 
    return Digit(m_nDigit == 9 ? 0 : (m_nDigit + 1)); 
} 

我想知道

  1. 是否有創造一個像我做了一個新的對象的任何缺點,並
  2. 關於如何選擇這些實現的呢?
+1

您的替代實現看起來像缺少'='。 – 2012-02-26 05:09:39

+1

@CarlNorum:修好了,對不起這個玩笑。 – Lazer 2012-02-26 05:21:26

回答

3

在你的備選實現你有2個問題:

  1. ,而不是m_nDigit = 9m_nDigit == 9。目前m_nDigit將始終爲9,並且返回值將始終爲0.

  2. 您應該更改m_nDigit的值。當返回0 - 你不。

return語句是有問題的,因爲操作符需要更改操作數的值,而不是創建新的對象。

編輯

爲了澄清這個問題,考慮代碼:

Digit x; 
x++; 

你會想到x是因爲這段代碼的結果呢?我期望它是1.使用您的操作員,它保持不變。

+0

我已經更新了這個問題。如果它創建一個新的對象,會出現什麼問題? – Lazer 2012-02-26 05:26:40

+0

@Lazer,你可以做任何你想做的事情,但是創建一個新對象並不符合前綴'++'操作符的正常語義。 – 2012-02-26 05:27:41

+0

@Lazer - 問題在於有人打電話給這個操作員的期望。當我有像'數字x; x ++;' - 會發生什麼,你怎麼看? – littleadv 2012-02-26 05:29:58

4

當然有不利的一面,你已經做了創建對象:

  1. 它不會編譯。將非const引用綁定到臨時表是不可能的。

  2. 即使它沒有編譯它不會執行正確的操作(你的版本讓operator++設置m_nDigit9,其他版本的增量m_nDigit,達到10當週圍包裹)。

  3. 即使它沒有編譯和做正確的事情,這將是非常不安全的。返回的引用將被綁定到函數返回前,它會被銷燬的臨時對象,這將意味着,任何企圖訪問由operator++的返回值引用的對象會導致未定義的行爲。

要在兩種實現中進行選擇,您應該選擇一種編譯,正確且安全的方法。

2
  1. m_nDigit = 9是一個任務,並會一直進行評估,以true
  2. 您返回對象的副本,但返回類型是引用。這可能會咬你(見Is returning a temp-object by reference possible)。
  3. 爲什麼不是m_nDigit = (m_nDigit + 1) % 9;
4

您對三元運算符有問題。此外,您正在返回對象的副本,而不是對象本身,如果您試圖重載操作符以像內置類型一樣工作,則應始終返回對該對象的引用。

我認爲你應該做這樣的:

Digit& Digit::operator++() 
{ 
    m_nDigit = (m_nDigit == 9 ? 0 : m_nDigit++); 
    return *this; 
} 

或者這樣:

Digit& Digit::operator++() 
{ 
    m_nDigit = (++m_nDigit % 10); 
    return *this; 
} 

創建新對象的缺點是,在這樣的代碼:

Digit d; 
++d; 

我認爲d的值會發生變化,而新的對象則不會。這個操作符在很多情況下都是這樣使用的(不將它賦值給一個變量),所以如果你不增加和返回同一個對象,就不能像這樣使用它。