重複の可能性:
未定義の動作とシーケンスポイント
接尾辞演算子をオーバーロードするときのアクションの順序を理解するのに問題があります。以下の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にインクリメントされます。次に、tempを返します。別のオブジェクトに割り当てる場合は、これで機能します。しかし、ここでは自己割り当てしているので、2にインクリメントした後myObject
は初期値で初期化された戻り値の一時オブジェクトと等しく設定され、1に戻ります。それは理にかなっている。しかし、それは根本的に異なる振る舞いです。
どうすれば回避できますか?intはどのようにそれを行いますか?このメソッドは一般的にどのように記述されていますか?これに関連するC++の動作と設計についてコメントはありますか?等本やオンラインの例は常に上記の方法の変形を使用しているように見えるので、私は今少し困惑しています。
読んでくれてありがとう、そしてどんな入力でも大歓迎です!