簡體   English   中英

Operator ++:引用vs值返回和未使用的參數

[英]Operator++: reference vs value return and unused argument

我看到這個C ++代碼是一個更大的例子的一部分:

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

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

首先,如果Date temp = *this ,那么我不明白為什么返回類型對於這兩個函數有什么不同? 一個返回*this ,另一個返回temp ,它被分配給*this

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

第一個返回this指向的對象作為引用。 也就是說,返回的對象調用operator++的對象。 但是,當你執行Date temp = *thistemp是從*this的值構造的。 然后將其復制出函數。 你從第二個函數得到的是一個全新的對象。 為什么函數有這種差異在第二個問題的答案中解釋。

有兩種類型的遞增運算符 - 一種是后遞增( i++ ),另一種是預遞增( ++i )。 為了能夠單獨重載它們(盡管它們具有相同的名稱, operator++ ),C ++標准指定后增量運算符采用int類型的參數和未指定的值。 這很簡單,您可以為操作員的每次使用重載該功能。 由於您不太可能想要使用未指定的值,因此您可以將其保留為未命名。

現在,預增量運算符的預期行為是它遞增對象並評估為該對象。 這就是它在這種情況下返回引用的原因。 后增量的預期行為是它保留原始值的副本,遞增對象然后返回原始值。 因此,它返回temp副本。

這是一個很好的問題 - 它突出了C ++設計師采用的一種相當愚蠢的設計選擇:

  • 沒有參數的重載是預先遞增的; 帶有未使用的 int參數的重載是后增量。
  • 這就是為什么預增量版本可以返回引用,而后增量必須在增加值本身之前復制原始版本。
  • 添加int參數的原因有一個 - 區分兩個重載; 它沒有任何意義,這就是為什么它的價值永遠不會被使用的原因。

第一個運算符是預遞增:它遞增值,並返回結果。 第二個是后增量:它遞增值,並返回先前的值。 在該代碼中, temp保存先前的值, helpIncrement()遞增該值,並返回先前的值( temp )。 參數沒有名稱的原因是它沒有被使用。 這有點像黑客; 編譯器知道++my_value應該被翻譯成my_value.operator++() ,並且my_value++應該被翻譯成my_value.operator++(1) 也就是說,缺少或存在積分參數決定了要調用的過載。

  1. 第一個函數在遞增后返回對此的引用。 第二個在遞增之前返回此副本。

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

這是一個基本主題,請閱讀有關重載operator++ 你可以從這里開始: 運算符重載

首先,如果Date temp = * this,那么我不明白為什么返回類型對於這兩個函數有什么不同?

讓我們將這與舊的int上的++的情況進行比較。 考慮

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

在此之后, j保持i的舊值,但是i自己增加了。 所以, i必須已經先於增量復制,仿佛++int被定義為

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

OTOH,之后

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

ij具有相同的值,因此++必須實現為

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

int更改為int&引入便利的地方:不需要復制,並且在需要引用的情況下可以使用++i

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

因為它永遠不應該被使用。 這個參數是作為一個語法噱頭,所以編譯器可以區分兩種類型的operator++ (前后增量),但它沒有任何明確定義的值。 賦予其名稱將在編譯器中觸發“未使用的標識符”選項並啟用適當的警告。

暫無
暫無

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

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