admin 管理员组

文章数量: 887021

push

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