6
vector<X> v;
X x;
v.push_back(x); v.push_back(x); v.push_back(x);

X このコードがクラスのコピーコンストラクターを6回呼び出すのはなぜですか?(g ++ 4.7.2 STLを使用)

この特定のSTLの内部で何が起こっているのかを正確に知りたいのですが。

4

4 に答える 4

12

を挿入するxpush_back()、メモリは最終的に再割り当てされ、新しい要素のためのスペースが確保されます。次に、すでに挿入されているメンバーを、コピーコンストラクターを使用してコピーする必要がありますX(const X&)

挿入した場合

v.reserve(3);

再割り当ては少なくとも最初の3秒間は防止さpush_back()れ、その結果、への呼び出しは3回だけになります。X(const X&)

于 2012-11-15T10:57:09.430 に答える
1

ベクトル予約を使用して、事前にベクトルにスペースを作成して、ベクトルへの要素の追加を高速化し、これが発生しないようにすることができます。

于 2012-11-15T10:59:37.027 に答える
1

正解はstd::vector、doubleing-array(http://en.wikipedia.org/wiki/Dynamic_array2 * Nを参照)を使用して実装され、コピーコンストラクターの約倍を呼び出すことです。

たとえばN = 100,000、コピーコンストラクターの231,071時間を呼び出します。指摘されているように、を呼び出すことで再割り当ての数を減らすことができますv.reserve()

于 2012-11-15T11:14:45.203 に答える
1

これが起こることです:

最初のpush_backの前は、ベクトルの容量(割り当てられたスペースに収まる要素の数)は0です。したがって、最初のpush_backを実行すると、1つのアイテムにスペースが割り当てられ、コピーコンストラクターが呼び出されます(最初の呼び出し)。 。

これで容量は1つになり、別のアイテムを追加するように指示します。したがって、より多くのスペース、この場合はもう1つのアイテム用のスペースを割り当て、元のアイテムを新しいスペースにコピーする必要があります(2回目の呼び出し)。2番目のpush_backは、コピーコンストラクターを再度呼び出します(3番目の呼び出し)。

これで2の容量があり、別のアイテムを追加するように指示します。したがって、より多くのスペースを割り当て、アイテムを新しいスペースにコピーする必要があります(4回目と5回目の呼び出し)。次に、3番目のpush_backがコピーコンストラクターを再度呼び出します(6番目の呼び出し)。

他の人が指摘しているように、reserveを使用すると、スペースを事前に割り当てることができ、再割り当ての必要がなくなり、コピーコンストラクターを呼び出す必要がなくなります。

于 2012-11-15T11:24:22.463 に答える