ベクトルを扱うとき、push_back 操作で必要となるのは数回のコピー コンストラクターの呼び出しのみであると予想されるかもしれません。ただし、複数の呼び出しなど、特定のケースでは予期しない動作が発生する可能性があります。
次のコード スニペットを考えてみましょう:
<code class="cpp">class Myint { int my_int; public: Myint() : my_int(0) { /* ... */ } Myint(const Myint& x) : my_int(x.my_int) { /* ... */ } }; int main() { vector<Myint> myints; Myint x; myints.push_back(x); // Call 1 x.set(1); myints.push_back(x); // Call 2 }</code>
直感的には、コピー コンストラクターの呼び出しが 2 つあると予想されます。1 つは最初の Push_back です。そして2番目にもう1つ。ただし、出力は別の話をします:
Call 1 (default constructor) Call 2 (copy constructor: my_int = 0) Call 3 (copy constructor: my_int = 0) Call 4 (copy constructor: my_int = 1)
なぜ余分な呼び出しが必要ですか?
内部では、ベクトルは通常、一定量のメモリをストレージ。割り当てられたスペースが使い果たされると、ベクターはさらに多くのメモリを再割り当てする必要があります。この再割り当てにより、既存の要素の新しいメモリへのコピーがトリガーされます。
指定されたコードでは、2 番目の Push_back で再割り当てが必要になります。 Myint のコンストラクターは 2 回しか呼び出されないにもかかわらず、コピー コンストラクターは 3 回利用されます。これは、コピー コンストラクターを使用して最初の要素を新しく割り当てられたメモリに移動し、元の値 (my_int = 0) で初期化され、次にコピー コンストラクターが再度呼び出され、更新された値 (my_int = 0) で初期化された 2 番目の要素が作成されるためです。 my_int = 1).
これらの不要なコピーを軽減するには、次のことをお勧めします。
この場合、reserve を使用してメモリを事前に割り当てると、コピー コンストラクターの呼び出しが効果的に 2 回に減ります。さらに、emplace_back(0) はコピーを完全に削除し、最適なパフォーマンスをもたらします。
以上が「push_back」がベクター内で複数のコピー コンストラクター呼び出しをトリガーするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。