2012-05-02 8 views
3

の結果を挿入した後、ベクターに表示されます。ごみは、私はこのように定義された演算子を持つオブジェクトを持っているオペレータ

ベクトル内に加算結果を直接代入した後、その内部にガベージが表示されます。

P p1(1.0, 0.0, 0.0); 
P p2(0.0, 0.0, 0.0); 

vector<P> v(1); 
v[0] = p1 + p2; // v[0] now contains garbage. 

私が変数を使って行う場合、すべてが期待通りです。

vector<P> u(1); 
P q = p1 + p2; 
u[0] = q; // u[0] contains correct value. 

このような現象は、どのような理由が考えられますか? 2つのケースの違いは何ですか?

+0

"*コピーまたは代入演算子がありません。*"特に定義していないことを意味しますか?その場合、暗黙的にコンパイラが定義されている可能性があります。それとも、あなたはあなたの道を離れてそれを無効にしたのですか? – ildjarn

+0

@ildjarn私はそれらを明確に定義していないと言っていました。それをもっと明確にするために私の質問を編集しました。 – Artium

+0

違うのは、上書きされた前に無効/削除された一時的なものから読み取られた2番目の例です。 (両方ともルールに反し、一時は死んでいる) –

答えて

10

一時的なものへの参照を返します。これは、関数の終わりに一時的なスコープ(この場合はoperator+関数)が外れるので、悪い考えです。あなたの演算子を次のように宣言してください:

P operator +(const P &rhs) const 

+0

これは 'P operator +(const P&rhs)const'でなければなりません - あなたが持っているように、移動セマンティクスは禁止されています。 – ildjarn

+0

@ildjarn:ありがとうございました。 – thiton

+0

私はこれが問題だと思ったが、結果をベクトルに代入するときに問題が生じるのはなぜですか? – Artium

3

あなたは

P& operator +(const P &rhs) 
{ 
    return P(x + rhs.x, y + rhs.y, z + rhs.z); 
} 

を見るであろうように機能operator +の範囲の外に一度破壊されたローカル変数への参照を返します。

ポインタをヒープで作成したデータに戻すことはできますが、呼び出し元がオブジェクトの削除に失敗した場合は、メモリリークのスコープが十分に残っています。

ます。また、コピーとしてオブジェクトを返すことができますが、時にはそれは、最近のC++ 11では、実際のオーバーヘッド

ことが今後の理想的かつ好ましいアプローチである必要があり、所有権を移転する動き構文を使用することができます。

+4

"*オブジェクトをコピーとして返すこともできますが、時には実際のオーバーヘッドになる可能性があります*"最新のコンパイラはすべて[RVO](http://en.wikipedia.org/wiki/Return_value_optimization)を実装しています。 – ildjarn

+0

@ildjarn:私は少し古いですね。 :-) – Abhijit

関連する問題