欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[c++] push_back和emplace_back的区别

程序员文章站 2022-03-21 17:04:20
...

介绍

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

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

相关标签: c++