2016-08-18 5 views
0

C++の移動セマンティクスの理解に問題があります。メソッドから大きなオブジェクトを返すとします。この操作を効率的にするために、私はラージオブジェクトクラスのための移動コンストラクタを使用します。大きなオブジェクトを取得し、それを処理する別のメソッドに渡すメソッドを呼び出します。移動コンストラクタはどのように機能しますか?

processLargeObject(getLargeObject()); 

私はラージオブジェクトを作成する方法getLargeObject()を記述します。新しい演算子を使用せずにオブジェクトを作成した場合、ストレージがスタックに割り当てられていることを理解しています。あらかじめオブジェクトのサイズを知っていて、それを配列で表現すると、この大きなオブジェクトはdouble foo[1000000000];と定義できます。今すぐ移動コンストラクタ内で、私は

foo = other.foo; 

を言うならば、移動したオブジェクトは、まだスタック上に存在し、スタックが拡大すると上書きすることができます。

これは、移動コンストラクタの使用方法であってはなりません。移動コンストラクタは、ヒープ上に存在する移動オブジェクトに対してのみ使用する必要がありますか?

+0

'foo'がdouble型の配列である場合、' foo = other.foo; 'はコンパイルされません。とにかく、どんなに正確な二倍体の配列を動かすことができますか? – Praetorian

+0

これは、配列をループしてコピーを作成する必要があることを意味しますか? – AggieMan

+0

宣言しようとしましたが、その中に普通の配列で10億倍の倍数を持つオブジェクトを使用しましたか?あなたのスタックをあふれさせる良い方法のようです。あなたは 'ベクトル'を使用していて、実際に移動するのが理にかなっているはずです。 – Praetorian

答えて

2

移動コンストラクタはどのように機能しますか?

移動コンストラクタは浅いコピーを行う必要があります - 深いとは対照的に、コピーコンストラクタが何をすべきことをコピーします。浅いコピーを行うことに加えて、ムーブコンストラクタは、移動されたオブジェクトによって指された任意のリソース(例えば、外部メモリバッファ、例えば、std::vectorが有するバッファ)を「盗む」。

この操作を効率的にするために、ラージオブジェクトクラスの移動コンストラクタを使用します。

厄介なことに、オブジェクト自体の大きさは、コピーよりも効率的に移動することはありません。移動は、オブジェクト「」が「盗難」する可能性がある大きなリソースに対して、を指し示すときに効率的です。そのような外部リソースがオブジェクトを "大きく"するものであることを意味するならば、十分に公正なものです。

移動コンストラクタは、ヒープ上にある移動オブジェクトに対してのみ使用する必要がありますか?

オブジェクトが格納されている場所にかかわらず、自動的、動的または静的であるから、移動できます。タイプが可動である限り。

この大きなオブジェクトが盗まれる可能性のある外部リソースを指していない非常に大きな物体の良い例であることdouble foo[1000000000];

として定義することができます。倍精度の配列を移動することは、それをコピーすることとまったく同じです。

+0

ありがとう。私はこの部分を持っています。私が得られないことは、移動したオブジェクトがヒープ上に存在する必要があるかどうかです。 – AggieMan

+0

@AggieManは編集を参照してください。 – user2079303

+0

移動コンストラクタが大きな利点をもたらすためには、データのほとんどは、オブジェクト内のポインタによって参照されるヒープ上のデータに格納する必要があります。 (したがって、 'std :: array 'は通常copy-constructと同じくらい高価ですが、1000000要素の 'std :: vector 'はmove-constructにとって非常に高速です。 ) –

関連する問題