0

私はデータ構造に関する本を読んでいましたが、現在、片方向リストのデータ構造を実装しようとしています。イテレータを実装しているときに、オーバーロードされたプレフィックスとポストフィックスのインクリメントの次の実装に出くわしました。

iterator &operator++()
{
    this->current = this->current->next;
    return *this;
}

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

最初のものはプレフィックス用で、2 番目のものはポストフィックス用であることはわかっていますが、オーバーロードされたポストフィックスのインクリメントのコードが異なるのはなぜですか? これを行うと何が問題になりますか?

iterator &operator++(int)
{
    this->current = this->current->next;
    return *this;
}

前もって感謝します。

4

1 に答える 1

9

実際には、両方の postfix バージョンが間違っています。後置反復子は、参照ではなくコピーを返さなければなりません。

ポイントは、ポストインクリメントはインクリメントされたオブジェクトを変更しますが、インクリメント前のバージョンを返すということです。プリインクリメントはオブジェクトを変更し、インクリメントされたバージョンを返します。それらのロジックは、それに応じて異なる必要があります。

この区別が行われるのは、ポストインクリメントとプリインクリメントがプリミティブ型に対して同じセマンティクスを持っているためです。例:

int i = 0;
std::cout << i++ << std::endl;

オーバーロードされた反復子を持つクラスは、一貫性のためにその動作を模倣する必要があります。示した反復子の実装の 1 つを使用して独自の整数クラスを作成した場合、結果は 1 になり、驚くべきことになります。

接尾辞インクリメントの正しい実装は、99% のケースにあります。

iterator operator++(int)
{
    iterator old = *this;
    ++(*this);
    return old;
}
于 2013-03-11T18:52:10.550 に答える