c++11 vector中push_back和emplace_back的區別

原文:https://blog.csdn.net/xiaolewennofollow/article/details/52559364

1、兩者區別

    在引入右值引用,轉移構造函數,轉移複製運算符之前,通常使用push_back()向容器中加入一個右值元素(臨時對象)的時候,首先會調用構造函數構造這個臨時對象,然後需要調用拷貝構造函數將這個臨時對象放入容器中。原來的臨時變量釋放。這樣造成的問題是臨時變量申請的資源就浪費。 
    引入了右值引用,轉移構造函數(請看這裏)後,push_back()右值時就會調用構造函數和轉移構造函數。在這上面有進一步優化的空間就是使用emplace_back,在容器尾部添加一個元素,這個元素原地構造,不需要觸發拷貝構造和轉移構造。而且調用形式更加簡潔,直接根據參數初始化臨時對象的成員。 

2、代碼實例

#include <vector>
#include <string>
#include <iostream>


struct President
{

    std::string name;
    std::string country;
    int year;

    //構造函數
    President(std::string p_name, std::string p_country, int p_year) : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }


    //複製構造函數
    President(const President& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being copy constructed.\n";
    }

    //轉移構造函數
    President(President&& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being moved.\n";
    }

    //賦值運算符函數
    President& operator=(const President& other);
};


int main()
{
    std::vector<President> elections;
    std::cout << "emplace_back:\n";
    elections.emplace_back("Nelson Mandela", "South Africa", 1994); //沒有類的創建

    std::vector<President> reElections;
    std::cout << "\npush_back:\n";
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));

    std::cout << "\nContents:\n";
    for (President const& president: elections) {
        std::cout << president.name << " was elected president of " << president.country << " in " << president.year << ".\n";
    }

    for (President const& president: reElections) {
        std::cout << president.name << " was re-elected president of " << president.country << " in " << president.year << ".\n";
    }
}

輸出:

emplace_back:
I am being constructed.


push_back:
I am being constructed.
I am being moved.


Contents:
Nelson Mandela was elected president of South Africa in 1994.

總結:

push_back()右值時就會調用構造函數和轉移構造函數

emplace_back()函數向容器中中加入臨時對象, 臨時對象原地構造,沒有賦值或移動的操作。

emplace_back()函數要比push_back()函數要快一倍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章