[c++] push_back和emplace_back的区别

介绍

emplace操作是C++11新特性,新引入的三个操作emplace_front、emplace 和 emplace_back,分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部[1]
本文以emplace_back和push_back为例讲解两者的区别。


区别

  1. 调用push_back时,参数为元素类型的对象,这个对象被拷贝到容器中。
  2. 调用emplace_back时,参数与该元素类型构造函数的参数相同,会在容器管理的内存空间内直接创建对象。

使用场景

有类A如下:

class A
{
public:
	A(int x) { x_ = x; };
	A(const A& a) { x_ = a.x_; };
private:
	int x_;
};
  1. 若push_back/emplace_back传递的参数为未被构造的对象,即在传递参数时构建对象,如vec.push_back(A(1)) / vec.emplace_back(1),这种情况下两种方法涉及的操作为
    push_back
    • 新建临时对象
    • 将该临时对象拷贝至容器末尾
    • 销毁该临时对象
    emplace_back
    • 在容器末尾新建对象
  2. 若push_back/emplace_back传递的参数为已被构造的对象,如A a(1); vec.push_back(a) / vec.emplace_back(a),这种情况下两种方法涉及的操作相同:
    push_back
    • 将该对象拷贝至容器末尾
    emplace_back
    • 将该对象拷贝至容器末尾

示例

代码:

#include <iostream>
#include <vector>


using namespace std;


class A
{
public:
    A (int x = 0) { x_ = x; cout << "constructor : " << x_ << endl; };
    A (const A& a) { x_ = a.x_; cout << "copy constructor : " << x_ << endl; };
    ~A () { cout << "destructor : " << x_ << endl; };

private:
    int x_;
};


int main()
{
    A a(2);
    cout << "##### push_back #####" << endl;
    vector<A> vec_push;
    cout << "capacity : " << vec_push.capacity() << endl << endl;

    vec_push.push_back(A(1));		// 未被构造的对象
    cout << "capacity : " << vec_push.capacity() << endl << endl;

    vec_push.push_back(a);			// 已被构造的对象
    cout << "capacity : " << vec_push.capacity() << endl << endl;

    
    cout << "\n\n##### emplace_back #####" << endl;
    vector<A> vec_emplace;
    cout << "capacity : " << vec_emplace.capacity() << endl << endl;

    vec_emplace.emplace_back(1);	// 未被构造的对象
    cout << "capacity : " << vec_emplace.capacity() << endl << endl;

    vec_emplace.emplace_back(a);	// 已被构造的对象
    cout << "capacity : " << vec_emplace.capacity() << endl << endl;
    

    cout << "\n\n##### exit #####" << endl;
    return 0;
}

运行结果:

constructor : 2
##### push_back #####
capacity : 0

constructor : 1
copy constructor : 1
destructor : 1
capacity : 1

copy constructor : 2
copy constructor : 1				# 这次拷贝构造的开销由vector扩容引起
destructor : 1						# 这次析构的开销由vector扩容引起
capacity : 2



##### emplace_back #####
capacity : 0

constructor : 1
capacity : 1

copy constructor : 2
copy constructor : 1				# 这次拷贝构造的开销由vector扩容引起
destructor : 1						# 这次析构的开销由vector扩容引起
capacity : 2



##### exit #####
destructor : 1
destructor : 2
destructor : 1
destructor : 2
destructor : 2

参考

[1] C++11新特性emplace操作
[2] C++无序关联容器(一)-使用场合和常用函数
[3] emplace与insert

如有错误,请大家及时指正 😃

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值