Vector の Push_back: 隠されたコピー コンストラクター呼び出しを明らかにする
わかりにくいシナリオでは、Vector の Push_back メソッドがコピー コンストラクターを呼び出しているように見えます。予想以上の回数。この動作を調べて、詳細を見ていきましょう。
提供されたコード スニペットを考えてみましょう。
<code class="cpp">class Myint { //... }; vector<Myint> myints; Myint x; myints.push_back(x); x.set(1); myints.push_back(x);</code>
最初に、x がベクトルにプッシュされます。予想どおり、初期化中に 1 つのコピーが発生します。しかし、出力を調べると、コピー コンストラクターが予期された 2 回ではなく、3 回呼び出されていることがわかります。この不一致の原因は何ですか?
ベクトルの内部動作が影響しています。ベクトルのスペースが不足すると、メモリを再割り当てする必要があります。この例では、2 番目の Push_back によって再割り当てがトリガーされます。 Myint には移動コンストラクターが暗黙的に定義されていないため、コピー コンストラクターが利用されます。その結果、最初の要素が新しく割り当てられたメモリにコピーされ、続いて x の 2 番目のコピーがコピーされます。この追加のコピーは、コピー コンストラクターの 3 回目の呼び出しを説明します。ここで、x には my_int が 1 に設定されています。
したがって、合計で 3 つのコピー コンストラクター呼び出しが発生します。この数は実装と初期ベクトル容量によって異なる場合がありますが、少なくとも 2 回の呼び出しが必要です。
これを軽減するには、reserve メソッドを使用して事前にさらに多くのメモリを予約することを検討してください。これにより、十分な容量が確保され、不必要な再割り当てが回避されます。
<code class="cpp">myints.reserve(2); // Allows two insertions without reallocation</code>
さらに、emplace_back メソッドを使用してコピーを削除できます。
<code class="cpp">myints.emplace_back(0); // Creates a new element directly in the vector</code>
Emplace_back は、コピーをバイパスして、コンストラクターに転送される任意の引数を受け取ります。または移動します。
以上が`vector::push_back` が予想以上にコピー コンストラクターを呼び出しているように見えるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。