0

コピー アンド スワップ方式を使用する場合の代入演算子について質問があります。

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
   s.swap (*this); // Non-throwing swap
   return *this;
}// Old resources released when destructor of s is called.

すべてのポインターと動的に割り当てられた変数をディープコピーする優れたコピー コンストラクターがあるとします。

では、上のコードと下のコードの違いは何ですか?

String & operator = (String s) // the pass-by-value parameter serves as a temporary
{
   return s;
}

良いコピー コンストラクターがあるので、別のオブジェクト s が operator= 関数内に作成されると思います。では、スローしないスワップ関数を使用するポイントは何ですか?

4

3 に答える 3

3

主な違いは、2 番目は現在のオブジェクト (つまり) をまったくoperator=変更しないことです。*this

String a, b;
b = a; // b is not changed at all

そして、2番目operator=が参照によって返さsれることに注意してください(関数から出ると破棄されます)ので、それはただのぶら下がった参照になります。


より一般的に言えば、コピーとスワップのイディオムを使用して、コミットまたはロールバックのセマンティクスのような強力な例外安全性の保証を提供します。例外が原因で操作が終了した場合、プログラムの状態は変更されません。

String & operator = (String s) // Copy construct s. If exception happens here, 
                               // s won't be constructed, 
                               // and the state of the current object (*this) won't be changed
{
   s.swap (*this);             // Use non-throwing swap to commit the change
   return *this;               // Non-throwing operation
}
于 2016-10-01T13:35:32.053 に答える
0

いくつかの主な違いがあります。

代入演算子は返す必要が*thisあります (ほとんどの場合、返されます)。これにより、連鎖代入が可能になります。

String s1, s2, s3;
s1 = s2 = s3; // Now all strings ave the same value.

代わりに、ローカル変数への参照を返します。有効なメモリ位置を指していないため、ダングリング参照になります。

また、代入演算子は割り当てられたオブジェクトを変更する必要がありますが、これはコードでは発生しません。

最後に、スローしないスワップが必要なのはなぜでしょうか? 代入演算子が例外をスローしたとしましょう。割り当てが失敗した後の、割り当てられたオブジェクトの状態は?

一部の実装では、オブジェクトの変更中に例外がスローされたため、オブジェクトが無効な状態になる可能性があります。

ここでスワップの出番です。スワップはスローされないため、割り当てられたオブジェクトが有効な状態であることを確認できます。スワップの前に例外がスローされた場合、オブジェクトはまだ古い値を保持しており、スワップの後であった場合、オブジェクトは新しい値を保持しています。

于 2016-10-01T13:44:12.930 に答える