vector中push_back和emplace_back区别

  • 区别测试代码
  • vector空间自动增长测试代码

正常情况下push_back是往vector中添加新的元素,只不过添加过程是先利用拷贝构造函数复制目标值,而 emplace_back可以 直接在目标位置上生成对象,这也正式emplace的原本放置的意思。
具体在使用上,如果push的对象元素是已经生成好了的(如Nelson),emplace_back和push_back可以认为没有区别,如果原本没有要push的这个元素,则直接原地生成效率较高;

实际在push的时候,由于vector内存需要连续,在vector size达到1, 2,4,8…时其长度需要自动增加,故四二次push时首先生成目标元素,检测到现有存储空间已满,会调用复制构造函数来重头到尾复制前面的vector元素,依次push进去vector之后再析构掉复制的元素,最后再将目标元素push进去;

一般移动构造函数的输入为右值,操作完成后右值内容就为空了(数字除外),具体过程可由std::move(左值) 进行模仿.
如果传入的为右值但没有定义移动构造函数,则可调用拷贝构造函数。即emplace_back和push_back均可接收左值(普通变量)和右值(无名临时对象),左值调用复制构造函数,右值调用移动构造函数,表现一致;

    President joy("joy ", "USA", 2021);elections.emplace_back(std::move(joy));elections.emplace_back(std::move(joy));elections.emplace_back(std::move(joy));
//输出结果
joy  elected president of USA in 2021.elected president of         in 2021.elected president of            in 2021.

emplace_back结果
elections.emplace_back(“Nelson Mandela”, “South Africa”, 1994)
I am being constructed.
elections.emplace_back(Nelson);
I am being constructed.
I am being copy constructed.
moved:
joy USA2021
elections.emplace_back(std::move(Nelson));
I am being constructed.
I am being moved.
moved:
2021

push_back结果
reElections.push_back(President(“Franklin Delano Roosevelt”, “the USA”, 1936))
I am being constructed.
I am being moved.
I am being destructed.
reElections.push_back(obama);
I am being constructed.
I am being copy constructed.
moved:
Franklin USA1966
reElections.push_back(std::move(obama));
I am being constructed.
I am being moved.
moved:
1966

区别测试代码

这里是参考博客 ().

// An highlighted block
#include <vector>
#include <string>
#include <iostream>  struct President
{  std::string name;  std::string country;  int year;  President(std::string p_name, std::string p_country, int p_year) //构造函数:name(p_name), country(p_country), year(p_year)  {  std::cout << "I am being constructed.\n"; }President(const President& other)  //拷贝构造函数:name(other.name), country(other.country), year(other.year){ std::cout << "I am being copy constructed.\n";}President(President&& other)        //移动构造函数:name(std::move(other.name)), country(std::move(other.country)), year(other.year)  { std::cout << "I am being moved.\n"; }  President& operator=(const President& other);  ~President(){ std::cout << "I am being destructed.\n";}
};  int main()
{  std::vector<President> elections;  std::cout << "emplace_back:\n";  elections.emplace_back("Nelson ", "frica", 1994); //没有类的移动elections.emplace_back("Nelson ", "Africa", 1995); elections.emplace_back("Nelson ", "Africa", 1996); President joy("joy ", "USA", 2021);elections.emplace_back(std::move(joy));std::vector<President> reElections;  std::cout << "\npush_back:\n";  reElections.push_back(President("Franklin ", "USA", 1936));  reElections.push_back(President("Franklin ", "USA", 1937));reElections.push_back(President("Franklin ", "USA", 1938));President obama("obama ", "USA", 1966);reElections.push_back(obama);std::cout << "moved:\n" << obama.name<< obama.country << obama.year <<std::endl;std::cout << "\nContents:\n";  for (President const& president: elections) {  std::cout << president.name << " elected president of "  << president.country << " in " << president.year << ".\n";  }  for (President const& president: reElections) {  std::cout << president.name << " re-elected president of "  << president.country << " in " << president.year << ".\n";  }
}

结果输出
emplace_back:
I am being constructed.
I am being constructed.
I am being copy constructed.
I am being destructed.
I am being constructed.
I am being copy constructed.
I am being copy constructed.
I am being destructed.
I am being destructed.

push_back:
I am being constructed.
I am being moved.
I am being destructed.
I am being constructed.
I am being moved.
I am being copy constructed.
I am being destructed.
I am being destructed.
I am being constructed.
I am being moved.
I am being copy constructed.
I am being copy constructed.
I am being destructed.
I am being destructed.
I am being destructed.

Contents:
Nelson elected president of frica in 1994.
Nelson elected president of Africa in 1995.
Nelson elected president of Africa in 1996.
Franklin re-elected president of USA in 1936.
Franklin re-elected president of USA in 1937.
Franklin re-elected president of USA in 1938.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.

vector空间自动增长测试代码

#include <iostream>
#include <vector>using std::cout;
using std::endl;struct X{X(int a) {x=a;cout << "调用构造函数:X()" << a << endl;}X(const X& Xa) {x=Xa.x; cout << "调用拷贝构造函数:X(const X&)" << x << endl;}~X(){cout << "调用析构函数:~X()" << x << endl;}int x;
};int main(int argc, char **argv)
{cout << "定义局部变量:" << endl;X x(1);X y(2);std::vector<X> vec;cout << "\n存放在容器:" << endl;vec.push_back(y);vec.push_back(x);vec.push_back(y);cout << endl;cout << "程序结束!!!" << endl;return 0;
}

输出结果

定义局部变量:
调用构造函数:X()1
调用构造函数:X()2
存放在容器:
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用拷贝构造函数:X(const X&)2
调用析构函数:~X()2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用析构函数:~X()2
调用析构函数:~X()1
程序结束!!!
调用析构函数:~X()2
调用析构函数:~X()1
调用析构函数:~X()2
调用析构函数:~X()2
调用析构函数:~X()1

vector中push_back和emplace_back区别相关推荐

  1. vector中push_back()和emplace_back()的区别

    emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同. push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝(调用拷贝构造函数) ...

  2. vector中resize()和reserve()区别

    vector中resize()和reserve()区别 本博客转载自:https://blog.csdn.net/jocodeoe/article/details/9230879 先看看<C++ ...

  3. C++:vector的push_back()与emplace_back()

    在STL中,向vector容器添加元素的函数有2个:push_back().emplace_back() 1.push_back() 在vector容器尾部添加一个元素,用法为: arr.push_b ...

  4. C++小实验之vector的 push_back 和 emplace_back 及其使用时机

    参考 参考一: 如果参数是左值,两个调用的都是copy constructor 如果参数是右值,两个调用的都是move constructor(C++ 11后push_back也支持右值) 最主要的区 ...

  5. std::vector中resize()和reserve()区别

    在STL容器中vector用的还是比较多的,但是在使用时,会对resize()和reserve()的使用产生迷惑,现在就对这一情况做个对比: resize():改变的是size()与capacity( ...

  6. 栈堆的emplace和push_C++姿势点: push_back和emplace_back

    网上最常讲的:C++ vector::push_back 会先创建临时对象,然后将临时对象拷贝到容器中,最后销毁临时对象:但是 emplace_back 仅会在容器中原地创建一个对象出来,减少临时对象 ...

  7. C++:vector中使用.clear()函数

    vector.clear()函数并不会把所有元素清零. vector有两个参数,一个是size,表示当前vector容器内存储的元素个数,一个是capacity,表示当前vector在内存中申请的这片 ...

  8. C++11介绍之vector::push_back和vector::emplace_back区别

    vector::push_back和vector::emplace_back区别 emplace_back() 和 push_back() 功能上类似,但底层实现机制是不同的.push_back() ...

  9. c++中list、vector、map 、set区别

    List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]. Vector对于随机 ...

  10. C++ Vector中size()和capacity()区别

    简单而言,size()指的是当前Vector中存放元素的大小,即他当前存放了多少个元素,capacity()指的是他能够存放多少个元素. 两个方法可以控制存放元素的大小和最大容纳数量 reserve可 ...

最新文章

  1. TensorFlow之会话
  2. “厌氧动物”出现,科学家不清楚代谢方式,或颠覆对生命的认知
  3. listener does not currently know of service requested in connect descriptor
  4. 测试php数字范围_你不知道的接口测试之拾遗
  5. [D3D] - 用PerfHUD来调试商业游戏
  6. Spring中任务调度cronExpression配置说明
  7. 中消协:要选择优质电子显示产品 OLED屏整体上略胜一筹
  8. vue读取外部配置文件
  9. 第一次接触WebSocket遇到的坑以及感受
  10. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式...
  11. Matlab图像标题_title
  12. 易语言调用大漠Ocr文字识别游戏角色坐标
  13. Ajax小实例   用户注册异步验证
  14. 原型图高保真和中保真的区别_最终确定您的高保真度UX概念验证
  15. 我的Java学习之路(三)-- 自动饮料售卖机控制台程序
  16. Tiny4412 LCD驱动(DRM+设备树)
  17. autojs ui界面模板3
  18. 【discuzx2】forum_index.php文件的分析
  19. 从SAP中查找BADI
  20. 走进Vue.js 1.0-姜威-专题视频课程

热门文章

  1. H5 HTML 移动端触摸拖拽drag drop 自定义拖拽样式 使用PointerEvent模拟的拖拽方案
  2. 龙贝格算法的实现以及与复合梯形公式精度的比较
  3. android实战:密码箱一
  4. python运行报错怎么看_解决python运行启动报错问题
  5. 必应 Bing 新特性之最新文章, Wolfram|Alpha 整合, 天气搜索等已推出
  6. 优秀程序员的博客有哪些?
  7. Java程序语言(基础篇)第2章 基本程序设计 编程练习题解答
  8. 真实世界里的钢铁侠-特斯拉汽车创始人埃隆·马斯克(Elon Musk)
  9. 动态规划 -- 活动时间问题
  10. springboot整合xxl-job