のは、あなたの構造ビットを拡張してみましょう:push_back
方法に
struct T {
T() {
std::cout << "Constructor\n";
}
T(const T&) {
std::cout << "Copy Constructor\n";
}
T(T&&) {
std::cout << "Move Constructor\n";
}
~T() {
std::cout << "Destructor\n";
}
};
、別のコール:
vec.push_back(T()); // 1
std::cout << "--- --- ---\n";
vec.push_back(T()); // 2
std::cout << "--- --- ---\n";
今、出力がより完全になります。
Constructor
Move Constructor
Destructor
--- --- ---
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
--- --- ---
Destructor
Destructor
最初のグループ:
210は、第1のpush_back
呼び出しに対応する:
vec.push_back(T()); // 1
出力を容易に解読されるかもしれない:
Constructor // Create a temporary
Move Constructor // Move a temporary into the internal vector storage
Destructor // Destroy a temporary
第二群:
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
は、第push_back
呼び出しに対応:
vec.push_back(T()); // 2
ともう少し複雑:
Constructor // create a temporary
Move Constructor // move it into the newly allocated vector storage
Copy Constructor // copy previously created element into the new storage
Destructor // destroy old storage
Destructor // destroy temporary
ここでは、ベクトルクラスは内部的にそのメモリを割り当て、すべての要素のenoghスペースを提供するために、それを管理していることを忘れてはなりません。だから、あなたはより多くの要素を追加する場合、新しい割り当てが起こると、古い要素をコピーまたは新しいストレージに移動されます。
既知のサイズの場合は、あなたは、単に要素の特定の数のための十分なメモリを確保しreserve
方法を、使用することがあります。それは(少なくともまで、あなたが予約サイズを超えない)ベクターに新しい要素を追加することでこれらの再配分中の不要なメモリ再割り当ておよびコピーまたは移動要素を避けることができます。
第三の群:
Destructor
Destructor
は、プログラムの終了時にベクトルvec
デストラクタコールに対応します。
コピーコンストラクタもインストルメントします。照らし出すかもしれない。また、 'push_back'呼び出しの前、後、間に何かを表示するのに役立ちます。このようにすれば、どのようなアクションに応答して、これらのコンストラクタとデストラクタがいつ発生するかを知ることができます。 –
emplace_backを一度、push_backを一度呼び出すことを意味しましたか? push_backを2回呼び出すポイントが表示されず、タイトルと一致しません。 –
ベクトルが記憶域を拡張する必要がある場合、ベクトルは新しい(大きな)チャンクを割り当て、元の要素を新しい記憶域にコピーまたは移動した後、元のファイルを破棄して古いメモリを解放します。余分なデストラクタ呼び出しは、おそらくそれに由来します。 –