1、push_back和emplace_back的区别

emplace_back() 和 push_back() 的区别

就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会在容器外创建这个元素然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);

而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

拷贝构造和移动构造函数的区别

移动构造函数是c++11的新特性,移动构造函数传入的参数是一个右值 用&&标出。一般来说左值可以通过使用std:move方法强制转换为右值。

首先讲讲拷贝构造函数:拷贝构造函数是先将传入的参数对象进行一次深拷贝,再传给新对象。这就会有一次拷贝对象的开销,并且进行了深拷贝,就需要给对象分配地址空间。

移动构造函数就是为了解决这个拷贝开销而产生的。移动构造函数首先将传递参数的内存地址空间接管,然后将内部所有指针设置为nullptr,并且在原地址上进行新对象的构造,最后调用原对象的的析构函数,这样做既不会产生额外的拷贝开销,也不会给新对象分配内存空间。

emplace_back() 函数在原理上比 push_back() 有了一定的改进,包括在内存优化方面和运行效率方面。内存优化主要体现在使用了就地构造(直接在容器内构造对象,不用拷贝一个复制品再使用)+强制类型转换的方法来实现,在运行效率方面,由于省去了拷贝构造过程,因此也有一定的提升。

代码示例:

  1. 先构造一个对象,再push_back(),触发拷贝构造;
  2. 如果push_back()前使用 std::move() 会触发移动构造;
  3. 如果传入参数是一个临时对象,使用push_back()会触发构造函数和移动构造而使用emplace_back()触发构造函数,少一次移动构造或拷贝构造
  4. 先构造一个对象,再emplace_back(),会触发拷贝构造;
  5. 如果emplace_back()前使用 std::move() 会触发移动构造;

2、什么情况下emplace_back性能能有所优化;

使用emplace_back插入临时对象要比使用push_back耗时更少。

临时对象

3、什么情况下其实并没有性能提升

正常已经存在的对象的情况下,两种方法差异不大。

4、什么时候使用std::move()

左值引用 和 右值引用

std::move并不能移动任何东西,它唯一的功能是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值.

使用 std::move()可以提升性能,可以在push_back()或emplace_back()时,将拷贝构造换成移动构造。

C++11引入了右值引用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数。

在这上面有进一步优化的空间就是使用emplace_back,在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。

std::move()使用的意义

协助使用者进行浅拷贝

5、结论:

1、push_back() 和 emplace_back()的使用;

如果是加入临时对象,emplace_back()可以减少一次移动构造的过程。

如果是其他情况,二者区别不大;

2、std::move()的使用

使用std::move()可以将左值转换成右值,

这样,在使用 push_back() 和 emplace_back()时,可以将拷贝构造换成移动构造,减少内存的消耗。

参考:

(待补充)

push_back、emplace_back、std::move相关推荐

  1. C++ push_back()和back() 、pop()、push()、emplace() 和 emplace_back()

    1 push_back()和back() 2 push_back()和pop_back( ) 3 push()和pop() 4 emplace() 和 emplace_back() 1 push_ba ...

  2. C++11:右值引用、移动构造、std::move, 以及使用emplace_back代替push_back

    最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 1.右值 ...

  3. 【C++ Primer | 16】std::move和std::forward、完美转发

    右值引用应该是C++11引入的一个非常重要的技术,因为它是移动语义(Move semantics)与完美转发(Perfect forwarding)的基石: 移动语义:将内存的所有权从一个对象转移到另 ...

  4. emplace、emplace_back等

    和前面学的 map.set 等容器一样,C++ 11 标准也为 unordered_map 容器新增了 emplace() 和 emplace_hint() 成员方法,本节将对它们的用法做详细的介绍. ...

  5. C++优化之使用emplace、emplace_back

    在C++开发过程中,我们经常会用STL的各种容器,比如vector,map,set等.在使用这些容器的过程中,我们会大量用到的操作就是插入操作,比如vector的push_back,map的inser ...

  6. C++之顺序性容器vector、list、deque的push_back、pop_back、push_front、pop_front、插入(insert)和删除(erase)通用操作及其变形

    一. push_back().pop_back().push_front().pop_front 二. insert之一. 例1: //小问学编程 #include <functional> ...

  7. std::vector中 begin()、end()、front()、back()的区别

    前言 之前看见std::vector 容器的begin().end().front().back()用法,了解begin()和end(),不了解front()和back()方法,今天没事查了下博客,验 ...

  8. 左值、右值和move语义

    左值.右值和move语义 左值.右值 左值引用 右值引用 move语义 参考教程 lvalues and rvalues in C++ Move Semantics in C++ 左值.右值 左值:可 ...

  9. 【c++】4.std::shared_ptr、std::make_shared、 .get() 、.data()、void *p 的用法、裸指针

    std::shared_ptr.std::make_shared. .get() ..data().void *p 的用法.裸指针 (1)shared_ptr能够记录对象被引用的次数,主要被用来管理动 ...

最新文章

  1. 四、垃圾收集之垃圾收集算法
  2. java反射 用处_浅谈Java反射
  3. ubuntu修改环境变量
  4. python计算机结构_python06--计算机内存结构与存储管理(P27)
  5. 浅谈游戏单位属性模块设计:属性组成、分级、计算与同步
  6. Map 3D中程序设置地图中心点
  7. 解密双十一小程序云背后毫秒级伸缩的Serverless计算平台:函数计算
  8. 湛江市计算机等级考试,2020广东省湛江市计算机等级考试注意事项
  9. TypeScript 素描-变量声明
  10. python运维是什么_什么是python自动化运维?
  11. android webview 无法加载插件,webView 测试问题,无法检测到 webView 控件
  12. 十年了,测试变了,我也变了,但总有一些东西未变
  13. ssm共享充电宝管理系统计算机毕业设计
  14. 【SOJ 385】旅馆
  15. 非标产品和标准产品的区别(关于3C)
  16. Nanopore测序技术
  17. 将链接转成base64格式生成二维码和把页面生成图片
  18. 计算机在生态文明建设的改造,关于中国生态文明建设的现状与未来思考
  19. 网狐获取服务器信息,网狐服务端扩展业务接口手册
  20. C++中LHS和RHS指什么

热门文章

  1. python3今日头条App电商数据抓取
  2. html锯齿边框,css3制作邮票(锯齿边框)-css3制作邮票(锯齿边框)-HTML5+CSS3-编玩编学- 注重积累的过程 快速锁定问题解决问题 写博客,在积累源码,持续更新技术博客,加分项...
  3. php富文本防注入_HTML Purifier,PHP中过滤富文本防止XSS攻击
  4. Ubuntu实现网络链接设置
  5. 图表控件TeeChart安装使用
  6. 随机矩阵 stochastic matrix
  7. 敏捷管理 -- 时间和成本管理
  8. linux电脑开机慢,Ubuntu 启动速度慢的解决方法
  9. 三星支付存在漏洞可导致黑客进行交易劫持
  10. 用word2vec解读延禧攻略人物关系