オブジェクトの自己割り当てを使用することは良い考えではないことを私は知っています。明らかに、このような自己割り当てを明示的に行う人は誰もいません。
MyClass obj;
obj = obj;
C++ がこれをサポートする理由はありますか、またはこれを使用する特定の状況はありますか?
Carl Norum と Ralph Tandetzky によって既に投稿された回答に加えて、コンパイラがすべての可能な自己代入を検出できるかどうか自問してください。
答えは明らかです。いいえ、できません。このかなり単純な (そしてばかげた) コードのスニペットを考えてみてください。
Class obj1;
Class obj2;
Class *ptr = &obj1;
if((rand() % 7) == 0)
ptr = &obj2;
obj2 = *ptr;
このコードは、自己割り当てになることがあります。コンパイラは警告する必要がありますか? ものによって?" Heisenberg Error #3: 7 の倍数を返す場合の自己代入rand()
rand
? " [0, 6] の範囲の数値のみを返す場合はどうなりますか?
これは、コンパイラーがかなり簡単に理解できる単純な例です。キャッチするのがはるかに困難なコードのより複雑なスニペットがありますが、コンパイラーがコードの広範なフロー分析を実行した場合はキャッチできますが、実行にははるかに時間がかかります。そしてもちろん、この動作を示す可能性のある非常に複雑なコード スニペットがあり、これを把握するのは非常に困難または不可能ですらあります。
そのため、潜在的な自己代入について確率的に警告するためだけに、実行にはるかに長い時間がかかるコンパイラを使用できます。率直に言って、それは警告しないよりも悪いことです。
これが問題であり、それを許可したくない場合は、「自己割り当てなし」というコーディング標準を用意してください。おそらくより良い考えです。
補足: 非常に洗練されたソース コード分析を実行して、問題を解決しようとするツールがあります。このようなツールは、いくつかの複雑なものを含む、そのような多くの自己割り当てを構成してキャッチすることができます。しかし、それでもすべてをキャッチできるわけではなく、実行に時間がかかり、通常は数千ドルの費用がかかります。
禁止する理由はないと思います。なぜですか?追加の言語ルールを作成するには? 私の知る限り、自己割り当ての実際の使用はありません。
割り当ての両側でオブジェクトを許可する正当な理由があります。たとえば、
obj = f( obj );
この線
obj = obj;
本当にその特別なケースです。
POD オブジェクトまたはコンストラクターのないオブジェクトのmay be used before initialized
場合、" " 警告を抑制するために使用できます (宣言されたローカル変数が実際に使用されていない場合は、削除する必要があります)。
ファイルまたは名前空間のスコープでは、他のグローバル オブジェクトのコンストラクターによって使用されているグローバル オブジェクトの初期化を防ぐためのハックとして使用できます。
std::list<Foo> g_foos;
自身をbeforeにFoo
追加した の静的インスタンスが実行されると、リストが空になり、登録が失われます。自己初期化はそれを防ぎます。g_foos
g_foos::g_foos()
std::list<Foo> g_foos = g_foos;
ただし、この問題を防ぐグローバル インスタンスを実装するためのより良い方法があります。たとえば、次のようになります。
std::list<Foo> & the_foos () {
static std::list<Foo> foos;
return foos;
}
禁止する本当の理由がないので、おそらく許可されます。個人的にはお勧めしませんが、未使用の変数警告の回避策として使用されているのを見てきました。