2

この C++ コードは、より大きな例の一部として見ました。

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

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

最初Date temp = *thisに if の場合、なぜこれら 2 つの関数の戻り値の型が異なるのかわかりませんか? 1 つは を返し*this、もう1 つはtempを返し*thisます。

次に、2 番目の関数のパラメーターに変数名がないのはなぜですか?

4

5 に答える 5

6

1 つ目は、 が指すオブジェクトを参照として返しますthis。つまり、返されるオブジェクトoperator++、呼び出されているオブジェクトです。ただし、 を実行するとDate temp = *thistempの値からコピーが作成されます*this。次に、関数からコピーされます。2 番目の関数から得られるのは、まったく新しいオブジェクトです。関数にこの違いがある理由は、2番目の質問への回答で説明されています。

i++インクリメント演算子には、ポスト インクリメント ( ) とプリ インクリメント ( )の 2 種類があります++i。それぞれを個別にオーバーロードできるようにするため (同じ名前operator++int. これは、演算子を使用するたびに関数をオーバーロードできるようにするためです。その未指定の値を使用する可能性は低いため、名前を付けないままにしておくこともできます。

ここで、プレインクリメント演算子の期待される動作は、オブジェクトをインクリメントし、そのオブジェクトであると評価することです。そのため、この場合は参照が返されます。ポストインクリメントの予想される動作は、元の値のコピーを保持し、オブジェクトをインクリメントしてから元の値を返すことです。したがって、tempコピーを返します。

于 2012-12-09T21:08:16.717 に答える
1

これは素晴らしい質問です。これは、C++ の設計者が取ったかなりばかげた設計上の選択を浮き彫りにしています。

  • 引数のないオーバーロードはプリインクリメントです。未使用 のパラメーターを使用したオーバーロードintはポスト インクリメントです。
  • そのため、プレインクリメント バージョンは参照を返すことができますが、ポスト インクリメントは値自体をインクリメントする前に元のコピーを作成する必要があります。
  • パラメータが追加されたint理由は 1 つで、2 つのオーバーロードを区別するためです。それ以外の場合は意味がないため、その値が使用されることはありません。
于 2012-12-09T21:07:21.680 に答える
1

最初の演算子はプリインクリメントです。値をインクリメントし、結果を返します。2 つ目はポストインクリメントです。値をインクリメントし、前の値を返します。そのコードでtempは、 は前の値を保持し、値をhelpIncrement()インクリメントして、前の値 ( temp) を返します。引数に名前がないのは、それが使用されていないためです。これはちょっとしたハックです。コンパイラは、++my_valueが に変換されmy_value.operator++()、それmy_value++が に変換されるべきであることを認識していmy_value.operator++(1)ます。つまり、整数引数の有無によって、呼び出すオーバーロードが決まります。

于 2012-12-09T21:07:38.140 に答える
1

まず、Date temp = *this の場合、これら 2 つの関数の戻り値の型が異なる理由がわかりません。

++これを古き良き時代の状況と比較してみましょうint。検討

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

この後、jの古い値を保持しますがi、それi自体はインクリメントされます。したがって、 onが次のように定義され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、参照が必要な状況で使用できます。

次に、2 番目の関数のパラメーターに変数名がないのはなぜですか?

絶対に使ってはいけないからです。引数は構文上のギミックとして存在するため、コンパイラは 2 つのタイプ (プレインクリメントとポストインクリメント) を互いに区別できますoperator++が、明確に定義された値はありません。名前を付けると、適切な警告が有効になっているコンパイラで「未使用の識別子」オプションがトリガーされます。

于 2012-12-09T21:16:51.023 に答える
1
  1. 最初の関数は、インクリメントされた後、これへの参照を返します。2 番目のものは、インクリメントされる前に、これのコピーを返します。

  2. int2 番目の関数の未使用のパラメーターは、 ++ 演算子の前置 (パラメーターなし) バージョンと後置 (単一パラメーター) バージョンを区別します。

これは基本的なトピックです。オーバーロードについて読んでくださいoperator++。ここから始めることができます:演算子のオーバーロード

于 2012-12-09T21:10:18.377 に答える