使用向量時,人們可能會期望 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>
直覺上,我們預期有兩個複製建構函式呼叫:一個用於第一個 push_back第二個是另一個。然而,輸出卻講述了一個不同的故事:
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)
為什麼需要額外的呼叫?
在內部,向量通常會分配一定量的記憶體貯存。當分配的空間耗盡時,向量必須重新分配更多記憶體。此重新分配會觸發將現有元素複製到新記憶體中。
在給定的程式碼中,第二個push_back需要重新分配。儘管 Myint 的建構子只被呼叫兩次,但複製建構子卻被使用了 3 次。這是因為複製建構函式用於將第一個元素移至新分配的記憶體中,並使用其原始值(my_int = 0) 進行初始化,然後再次呼叫複製建構函式來建立第二個元素,並使用更新後的值進行初始化( my_int = 1).
為了減少這些不必要的副本,建議:
在這種情況下,使用保留來預先分配記憶體可以有效地將複製建構函式呼叫減少到兩次。此外,emplace_back(0) 將完全消除複製,從而實現最佳效能。
以上是為什麼 `push_back` 會在向量中觸發多個複製建構函式呼叫?的詳細內容。更多資訊請關注PHP中文網其他相關文章!