讓我們擴展您的結構位:
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";
}
};
和獨立的呼叫push_back
方法:
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
第一組:
Constructor
Move Constructor
Destructor
對應於第一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的點,它與您的標題不匹配。 –
當矢量需要增長其存儲空間時,它會分配新的(更大的)內存塊,將原始元素複製或移動到新的存儲空間,然後銷燬原始內存並釋放舊內存。額外的析構函數調用可能來自於此。 –