簡體   English   中英

實現前綴運算符++

[英]implementing prefix operator++

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. 它不會編譯。 將非常量引用綁定到臨時對象是不可能的。

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

  3. 即使它確實編譯並做了正確的事情,也將是非常不安全的。 返回的引用將綁定到一個臨時對象,該對象將在函數返回之前被銷毀,這意味着任何嘗試訪問operator++返回值所引用的對象都將導致未定義的行為。

要在這兩種實現之間進行選擇,您應該選擇一種可以編譯,正確且安全的實現。

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

我認為您應該這樣做:

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的值能夠更改,而對於新對象則不會。 在很多情況下都使用此運算符(不將其分配給變量),因此,如果不增加並返回相同的對象,就不能那樣使用它。

在您的替代實現中,您有2個問題:

  1. 代替m_nDigit = 9m_nDigit == 9 當前, m_nDigit始終為9,返回值始終為0。

  2. 您應該更改m_nDigit的值。 返回0時-您不這樣做。

return語句有問題,因為期望運算符更改操作數的值,而不是創建新的對象。

編輯

為了澄清問題,請考慮以下代碼:

Digit x;
x++;

您希望x作為此代碼的結果是什么? 我希望它是1。使用您的運算符,它將保持不變。

  1. m_nDigit = 9是一個賦值,它將始終被評估為true
  2. 您返回對象的副本,但返回類型是引用。 這可能會咬你(請參閱可以通過引用返回臨時對象 )。
  3. 為什么不m_nDigit = (m_nDigit + 1) % 9;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM