C++:vector的push_back()与emplace_back()
在STL中,向vector容器添加元素的函数有2个:push_back()、emplace_back()
1.push_back()
在vector容器尾部添加一个元素,用法为:
arr.push_back(val);
2.emplace_back()
C++11新增,功能与push_back相同,向vector容器尾部添加一个元素,用法为:
arr.emplace_back(value);
3.区别
可以发现push_back()与emplace_back()在用法上没有区别,主要的区别在于底层实现的机制不同。
push_bakc()添加元素时,首先会创建这个元素,然后再将这个元素拷贝或移动到容器中(如果是拷贝的话,事后会自行销毁之前创建的这个元素);emplace_back()添加元素时,则是直接在尾部创建这个元素,省去了拷贝或移动元素的过程。
1)第一个测试用例:直接传递构造参数插入
#include<iostream>
#include<string>
#include<cstring>
#include<string.h>
#include<vector>
using namespace std;
class A{
private :int n;
public:A(int num):n(num){cout<<"执行构造函数"<<endl;}A(const A &a):n(a.n){cout<<"执行拷贝构造函数"<<endl;}A(A&& a):n(a.n){cout<<"执行移动构造函数"<<endl;}~A(){}};
int main()
{vector<A> test1,test2;cout<<"push_back():::::"<<endl;test1.push_back(20);cout<<"emplace_back():::::::"<<endl;test2.emplace_back(20);return 0;
}
执行之后的输出为
push_back():::::
执行构造函数
执行移动构造函数
emplace_back():::::::
执行构造函数
当将类A中的移动构造函数注释掉,变成如下:
class A{
private :int n;
public:A(int num):n(num){cout<<"执行构造函数"<<endl;}A(const A &a):n(a.n){cout<<"执行拷贝构造函数"<<endl;}~A(){}
};
执行结果为:
push_back():::::
执行构造函数
执行拷贝构造函数
emplace_back():::::::
执行构造函数
可以发现:push_back()会优先调用移动构造函数,若没有则调用拷贝构造函数;且同样的操作,push_back()比emplace_back()的实现更繁琐,即emplace_back()的执行效率更高。
emplace_back()在内存与运行效率方面都优于push_back()。内存方面emplace_bakc()是就地构造,不用拷贝一个再使用;在效率方面,由于省去了拷贝构造过程,执行效率更高。
2)第2个测试用例:传递临时对象
#include<iostream>
#include<string>
#include<cstring>
#include<string.h>
#include<vector>
using namespace std;
class A{
private :int n;
public:A(int num):n(num){cout<<"执行构造函数"<<endl;}A(const A &a):n(a.n){cout<<"执行拷贝构造函数"<<endl;}A(A&& a):n(a.n){cout<<"执行移动构造函数"<<endl;}~A(){}
};
int main()
{vector<A> test1,test2;cout<<"push_back():::::"<<endl;test1.push_back(A(20));cout<<"emplace_back():::::::"<<endl;test2.emplace_back(A(20));return 0;
}
此时执行结果为:
push_back():::::
执行构造函数
执行移动构造函数
emplace_back():::::::
执行构造函数
执行移动构造函数
可以发现:
此时push_back()与emplace_back()的效率是一样的。
3)第3个测试用例:传递对象实例
#include<iostream>
#include<string>
#include<cstring>
#include<string.h>
#include<vector>
using namespace std;
class A{
private :int n;
public:A(int num):n(num){cout<<"执行构造函数"<<endl;}A(const A &a):n(a.n){cout<<"执行拷贝构造函数"<<endl;}A(A&& a):n(a.n){cout<<"执行移动构造函数"<<endl;}~A(){}
};
int main()
{A a(20);vector<A> test1,test2;cout<<"push_back():::::"<<endl;test1.push_back(a);cout<<"emplace_back():::::::"<<endl;test2.emplace_back(a);return 0;
}
此时执行结果为:
执行构造函数
push_back():::::
执行拷贝构造函数
emplace_back():::::::
执行拷贝构造函数
可以发现:
此时push_back()与emplace_back()的效率是一样的。
4)第4个测试用例:多个参数
#include<iostream>
#include<string>
#include<cstring>
#include<string.h>
#include<vector>
using namespace std;
class A{
private :int m;int n;
public:A(int num1,int num2):m(num1),n(num2){cout<<"执行构造函数"<<endl;}A(const A &a):n(a.n){cout<<"执行拷贝构造函数"<<endl;}A(A&& a):n(a.n){cout<<"执行移动构造函数"<<endl;}~A(){}
};
int main()
{vector<A> test1,test2;cout<<"emplace_back():::::::"<<endl;test2.emplace_back(10,20);cout<<"push_back():::::"<<endl;test1.push_back(30,40);/会报错return 0;
}
此时发现,报如下错误:
requires single argument '__x', but 2 arguments were provided_LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
即push_back()只需要一个参数,但传递了2个参数。
总结:
一般情况下,emplace_back()在内存方面和运行效率方面优于push_back(),但传递临时对象或对象实例时二者效率没有区别;
emplace_back()支持直接传递多个构造函数参数;
push_back()仅支持直接传递一个构造函数参数,若构造函数有多个参数,可以传递对象。
C++:vector的push_back()与emplace_back()相关推荐
- C++小实验之vector的 push_back 和 emplace_back 及其使用时机
参考 参考一: 如果参数是左值,两个调用的都是copy constructor 如果参数是右值,两个调用的都是move constructor(C++ 11后push_back也支持右值) 最主要的区 ...
- vector中push_back()和emplace_back()的区别
emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同. push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝(调用拷贝构造函数) ...
- push_back()和emplace_back()函数
参考原文:http://c.biancheng.net/view/6826.html 要知道,向 vector 容器中添加元素的唯一方式就是使用它的成员函数,如果不调用成员函数,非成员函数既不能添加也 ...
- push_back 和 emplace_back 剖析
文章目录 前言 一.源码 二.共同点 三.优化点 总结 前言 仓库推荐 C/C++ 每日一练小仓库,慢慢学习C++ 知识必备仓库 https://github.com/yeshenyong/pract ...
- push_back()和emplace_back()详解
学习链接:C++ STL vector添加元素(push_back()和emplace_back())详解 1. emplace_back C++11新增:与push_back功能相同,在vector ...
- 栈堆的emplace和push_C++姿势点: push_back和emplace_back
网上最常讲的:C++ vector::push_back 会先创建临时对象,然后将临时对象拷贝到容器中,最后销毁临时对象:但是 emplace_back 仅会在容器中原地创建一个对象出来,减少临时对象 ...
- push_back、emplace_back、std::move
1.push_back和emplace_back的区别 emplace_back() 和 push_back() 的区别: 就在于底层实现的机制不同.push_back() 向容器尾部添加元素时,首先 ...
- vector的push_back拷贝构造和空间占用分析
本文同步自:http://zohead.com/archives/vector-push-back-space-copy/ 这两天在实际程序中使用 STL 的 vector push_back 类对象 ...
- c++ 11 vector push_back和emplace_back速度比较
对比两种push方法的效率及速度: #include<stdio.h> #include<time.h> #include<iostream> #include&l ...
最新文章
- JSTL标签显示分页
- Django 3.2.5博客开发教程:体验django模板
- Centos Apache服务搭建
- configurations in Gateway hub system
- 简单的C语言五子棋(两种模式:移动光标输入坐标和移动光标按键)
- 一文详解Redis中BigKey、HotKey的发现与处理
- BlueCatTools-域名批量查询软件介绍
- html/jsp下载Excel文件
- Illustrator 教程,如何在 Illustrator 文档中缩放和平移?
- 模糊PID控制器设计
- 更改计算机时间出现没有权限,win7系统修改时间时显示没有权限的解决方法
- CCNA上机实验_19-PPP
- MATLAB双目标定步骤
- 学习虚幻4(一)U3D与UE4的比较
- 联想为什么不卖X系列服务器,IBM欲向联想出售x86服务器业务,涉及System x产品线...
- 赋能 打造应对不确定性的敏捷团队 pdf_赋能,打造应对不确定性的敏捷团队读后感(一)...
- 计算新闻传播学临摹作业_数据抓取与数据清洗(西安交大国家艺术基金数据可视化培训第34天)
- vant 表单按钮置灰_Vant Button 按钮
- android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...
- Rserve的R语言客户端RSclient