30

私はC++について、より正確には演算子のオーバーロードについての本を読んでいます。

例は次のとおりです。

const Array &Array::operator=(const Array &right)
{
// check self-assignment
// if not self- assignment do the copying
return *this; //enables x=y=z
}

refの代わりにconstrefを返すことについての本によって提供される説明は、(x = y)=zのような割り当てを避けることです。なぜこれを避けるべきなのか分かりません。この例ではx=yが最初に評価され、const参照が返されるため、=z部分を実行できないことを理解しています。しかし、なぜ?

4

5 に答える 5

31

(x=y)を意味x.operator=(y)し、オブジェクトを返しますx。したがって、(x=y)=zを意味し(x.operator=(y)).operator=(z)ます。括弧内の式はに設定xされyて戻りx、次に外側のビットはに設定xされzます。期待どおりに設定されておらず、式のようにy設定されていません。zx = y = z

この振る舞いは直感に反します(割り当て後はすべて同じである必要がありますよね?)。const参照を返すと、それが不可能になり、問題が回避されます。

于 2011-01-16T17:04:20.560 に答える
22

(x=y)=zこの本が一般的に意味するときに書くプログラマーを対象としているのでない限り、これを回避する必要はありませんx=y=z。実際には、正しい心の誰もそれを書いていませんので、予防策は完全に不要です。また、など、他の簡潔な構成を禁止します。これは(x=y).nonConstMember()、ほとんど誰も記述しませんが、一部のコンテキストでは役立つ可能性があります(ただし、過度に使用することはできません)。

@ybungalobillは正しいです、より良い本を手に入れてください。

于 2011-01-16T17:07:17.587 に答える
14

私の知る限り、代入演算子は慣用的なC++ではconst参照を返しません。標準タイプもconst参照を返しません。

std::string a, b, c;
(a = b).clear(); // no objection from compiler

私のカスタム代入演算子はすべて、非定数参照を返しました。

疑わしい場合は、標準ライブラリを確認してください。それは完璧ではありませんが、それは間違いなくこのような基本的なことを正しくします。

于 2011-01-16T17:18:09.520 に答える
4

組み込み型の動作を見てみましょう。

独自の型を定義するときは、演算子が組み込み型と同じように動作することが望ましいです。これにより、コードを掘り下げて、予想とは異なる動作をする理由を確認することなく、クラスを簡単に採用できます。

したがって、整数を見ると、次のようになります。

int main()
{
    int x = 5;
    int y = 6;
    int z = 7;

    (x = y) = z;
    std::cout << x << " " << y << " " << z << "\n";
}

これは、yが変更されず、xが割り当てられている場合に機能します。7。コードでは、代入演算子が同じように機能することを期待しています。標準の代入演算子の定義:

Array& Array::operator=(Array const& rhs)
{
    /* STUFF */
    return *this;
}

それはうまくいくはずです(/ * STUFF * /が正しいと仮定します)。

于 2011-01-16T17:44:32.577 に答える
1

私が見ることができる唯一の理由は、この本がC ++をCプログラマーに(またはC++の理解よりもCの理解が優れている著者によって)説明するために書かれたということです。Cプログラマーの場合、この式(x = y) = zは組み込み型では無効であり、ユーザー定義型でも同じ動作をしようとする可能性があります。

ただし、CとC ++は異なる言語であり、C ++では、式(x = y) = zは組み込み型に対しても有効です。したがって、ユーザー定義型に対して同じ動作をしたい場合は、で非定数参照を返す必要がありますoperator =

CとC++を混同しない、より良い本を入手することをお勧めします。それらが共通のベースから派生しているとしても、それらは同じ言語ではありません。

于 2011-01-16T18:12:42.833 に答える