可能性の重複:
Undefined Behavior and Sequence PointsのPostfix演算子のオーバーロード注文
後置演算子をオーバーロードするとき、私はアクションの順序を理解するトラブルを抱えています。以下の2つの小さな例を調べてみましょう:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
2つの非常に異なる動作が出現します。出力は次のようになります。
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
異なる動作があります。私のオーバーロードされた演算子メソッドの概要を次に示します。
MyClass & MyClass::operator++()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
いいえ。プレフィックスは意味があります。あなたは必要なものを増やして、同じオブジェクトを返します。割り当てられた場合は、変更されました。しかし、ポストフィックスは私を踏み外すものです。割り当てをしてからインクリメントするはずです。ここで私たちは自分自身を割り当てています。したがって、組み込みの整数型では意味があります。私はi
の値をそれ自身に割り当て、次にi
が増分されます。けっこうだ。しかし、MyClass
がintのレクリエーションであるとしましょう。 0から始まり、接頭辞をインクリメントして1になります。次に、キー行。 myObject = myObject++
。それはmyObject = myObject.operator++(int postfixFlag)
と同じことです。それは呼び出される。 myTemp
は値1で初期化されます.2にインクリメントされます。これは、別のオブジェクトに割り当てている場合に機能します。しかしここで私は自分自身を割り当てているので、2にインクリメントした後、myObject
は、初期値で初期化された返されたtempオブジェクトと等しく設定され、1に戻ります!それは理にかなっている。しかし、それは根本的に異なる行動です。
どうすれば回避できますか? intはどうしますか?この方法は一般にどのように書かれていますか?これに関するC++の動作とデザインに関するコメントはありますか?書籍やオンラインの例は、常に上の方法でバリアントを使用するように見えるので、私はちょっと困っています。
読んでいただきありがとうございました。ご了承ください。
'私は=私++が'と私= ++ i'両方定義されていない動作を示します。 –
あなたの 'int'の振る舞いは未定義です...異なるコンパイラ、バージョン、最適化レベル、ターゲットCPUで異なる結果を得ることができます。まったく明らかな理由もありません。*シーケンスポイントをバックグラウンドで読む必要があります* ...ここにはたくさんの質問がありますそれらに対処する。 –
[C++ FAQ](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points)もあります。 – Xeo