vector中push_back和emplace_back区别

vector中push_back和emplace_back区别

正常情况下push_back是往vector中添加新的元素,只不过添加过程是先利用拷贝构造函数复制目标值,而 emplace_back可以 直接在目标位置上生成对象,这也正式emplace的原本放置的意思。
具体在使用上,如果push的对象元素是已经生成好了的(如Nelson),emplace_back和push_back可以认为没有区别,如果原本没有要push的这个元素,则直接原地生成效率较高;

实际在push的时候,由于vector内存需要连续,在vector size达到1, 2,4,8…时其长度需要自动增加,故四二次push时首先生成目标元素,检测到现有存储空间已满,会调用复制构造函数来重头到尾复制前面的vector元素,依次push进去vector之后再析构掉复制的元素,最后再将目标元素push进去;

一般移动构造函数的输入为右值,操作完成后右值内容就为空了(数字除外),具体过程可由std::move(左值) 进行模仿.
如果传入的为右值但没有定义移动构造函数,则可调用拷贝构造函数。即emplace_back和push_back均可接收左值(普通变量)和右值(无名临时对象),左值调用复制构造函数,右值调用移动构造函数,表现一致;

    President joy("joy ", "USA", 2021);
    elections.emplace_back(std::move(joy));
    elections.emplace_back(std::move(joy));
    elections.emplace_back(std::move(joy));
//输出结果
joy  elected president of USA in 2021.
	  elected president of 		   in 2021.
 	  elected president of 		   in 2021.

emplace_back结果
elections.emplace_back(“Nelson Mandela”, “South Africa”, 1994)
I am being constructed.
elections.emplace_back(Nelson);
I am being constructed.
I am being copy constructed.
moved:
joy USA2021
elections.emplace_back(std::move(Nelson));
I am being constructed.
I am being moved.
moved:
2021

push_back结果
reElections.push_back(President(“Franklin Delano Roosevelt”, “the USA”, 1936))
I am being constructed.
I am being moved.
I am being destructed.
reElections.push_back(obama);
I am being constructed.
I am being copy constructed.
moved:
Franklin USA1966
reElections.push_back(std::move(obama));
I am being constructed.
I am being moved.
moved:
1966

区别测试代码

这里是参考博客 ().

// An highlighted block
#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(p_name), country(p_country), year(p_year)  
    {  std::cout << "I am being constructed.\n"; }
    
    President(const President& other)	//拷贝构造函数
    :name(other.name), country(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);  
    
    ~President()
    { std::cout << "I am being destructed.\n";} 
};  

int main()  
{  
    std::vector<President> elections;  
    std::cout << "emplace_back:\n";  
    elections.emplace_back("Nelson ", "frica", 1994); //没有类的移动
    elections.emplace_back("Nelson ", "Africa", 1995); 
    elections.emplace_back("Nelson ", "Africa", 1996); 
        President joy("joy ", "USA", 2021);
    elections.emplace_back(std::move(joy));

    
    std::vector<President> reElections;  
    std::cout << "\npush_back:\n";  
    reElections.push_back(President("Franklin ", "USA", 1936));  
    reElections.push_back(President("Franklin ", "USA", 1937));
    reElections.push_back(President("Franklin ", "USA", 1938));
    
    President obama("obama ", "USA", 1966);
    reElections.push_back(obama);
    std::cout << "moved:\n" << obama.name
         << obama.country << obama.year <<std::endl;
    std::cout << "\nContents:\n";  
    for (President const& president: elections) {  
       std::cout << president.name << " elected president of "  
            << president.country << " in " << president.year << ".\n";  
    }  
    for (President const& president: reElections) {  
        std::cout << president.name << " re-elected president of "  
            << president.country << " in " << president.year << ".\n";  
    }
}

结果输出
emplace_back:
I am being constructed.
I am being constructed.
I am being copy constructed.
I am being destructed.
I am being constructed.
I am being copy constructed.
I am being copy constructed.
I am being destructed.
I am being destructed.

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

Contents:
Nelson elected president of frica in 1994.
Nelson elected president of Africa in 1995.
Nelson elected president of Africa in 1996.
Franklin re-elected president of USA in 1936.
Franklin re-elected president of USA in 1937.
Franklin re-elected president of USA in 1938.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.

vector空间自动增长测试代码

#include <iostream>
#include <vector>

using std::cout; 
using std::endl;

struct X{
    X(int a) {x=a;cout << "调用构造函数:X()" << a << endl;}
    X(const X& Xa) {x=Xa.x; cout << "调用拷贝构造函数:X(const X&)" << x << endl;}
    ~X(){cout << "调用析构函数:~X()" << x << endl;}
	int x;
};

int main(int argc, char **argv)
{
    cout << "定义局部变量:" << endl;
    X x(1);
	X y(2);

    std::vector<X> vec;
    cout << "\n存放在容器:" << endl;
    vec.push_back(y);
	vec.push_back(x);
	vec.push_back(y);
    cout << endl;

    cout << "程序结束!!!" << endl;
    return 0;
}

输出结果

定义局部变量:
调用构造函数:X()1
调用构造函数:X()2
存放在容器:
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用拷贝构造函数:X(const X&)2
调用析构函数:~X()2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用析构函数:~X()2
调用析构函数:~X()1
程序结束!!!
调用析构函数:~X()2
调用析构函数:~X()1
调用析构函数:~X()2
调用析构函数:~X()2
调用析构函数:~X()1

  • 3
    点赞
  • 10
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

beta117

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值