首頁  >  文章  >  後端開發  >  為什麼 `push_back` 會在向量中觸發多個複製建構函式呼叫?

為什麼 `push_back` 會在向量中觸發多個複製建構函式呼叫?

Barbara Streisand
Barbara Streisand原創
2024-11-01 07:17:02533瀏覽

Why Does `push_back` Trigger Multiple Copy Constructor Calls in a Vector?

向量 Push_back 和多次複製建構子呼叫的奧秘

使用向量時,人們可能會期望 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:此方法允許您直接就地構造元素,避免複製或移動。

在這種情況下,使用保留來預先分配記憶體可以有效地將複製建構函式呼叫減少到兩次。此外,emplace_back(0) 將完全消除複製,從而實現最佳效能。

以上是為什麼 `push_back` 會在向量中觸發多個複製建構函式呼叫?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn