当前位置: 首页 > news >正文

vector的push_back和emplace_back核心区别

vector的push_back和emplace_back核心区别(原理+场景+性能)

push_backemplace_back是C++ vector向尾部添加元素的两个核心接口,核心差异在于元素构造方式push_back依赖“先构造(或拷贝)再插入”,emplace_back支持“原地构造”,后者在多数场景下更高效,也是C++11及以后的推荐用法。

一、核心区别:构造方式与参数传递

1. push_back:插入“已构造的对象”

push_back的核心逻辑是接收一个已构造的对象(或对象的拷贝/移动),将其复制/移动到vector的内存空间中:

  • 若传入“临时对象”:先构造临时对象 → 再移动(C++11+)/拷贝到vector;
  • 若传入“已有对象”:直接拷贝到vector;
  • 本质:push_back的参数是对象本身,要求传入的参数能直接构造出目标类型的对象。
示例(push_back):
#include<vector>#include<string>usingnamespacestd;classPerson{public:string name;intage;// 带参构造函数Person(string n,inta):name(n),age(a){}// 拷贝构造函数Person(constPerson&other):name(other.name),age(other.age){}// 移动构造函数(C++11)Person(Person&&other)noexcept:name(move(other.name)),age(other.age){}};intmain(){vector<Person>vec;// 方式1:先构造对象,再拷贝到vectorPersonp("Alice",20);vec.push_back(p);// 调用拷贝构造// 方式2:构造临时对象,再移动到vector(C++11+)vec.push_back(Person("Bob",25));// 临时对象→移动构造// 等价于 vec.push_back({"Bob", 25});(列表初始化)return0;}

2. emplace_back:原地构造对象(C++11新增)

emplace_back的核心逻辑是接收构造对象所需的参数,直接在vector的尾部内存空间原地构造对象,完全避免临时对象的创建和拷贝/移动:

  • 本质:emplace_back的参数是对象构造所需的参数,而非对象本身;
  • 底层:通过“完美转发”将参数传递给对象的构造函数,在vector的内存中直接构造元素。
示例(emplace_back):
#include<vector>#include<string>usingnamespacestd;// 复用上述Person类intmain(){vector<Person>vec;// 直接传入构造参数,原地构造Person对象vec.emplace_back("Charlie",30);// 无临时对象,直接调用Person(string, int)构造return0;}

二、关键差异对比表

特性push_backemplace_back
参数类型目标类型的对象(或引用/右值引用)目标类型构造函数的参数(任意数量/类型)
构造方式先构造对象(或拷贝),再插入直接在vector内存中原地构造
临时对象传入临时值时会创建临时对象无临时对象
函数重载有两个重载:const T&(拷贝)、T&&(移动)模板函数,支持完美转发任意参数
适用场景插入已有对象、简单类型(int/string)插入新对象(需传构造参数)、自定义类型
性能有拷贝/移动开销(临时对象)无拷贝/移动开销,效率更高

三、性能差异:何时emplace_back更优?

1. 自定义类型(多参数构造)

对于需要多参数构造的自定义类型,emplace_back避免了“临时对象构造+移动/拷贝”的开销,性能优势明显:

  • push_back(Person("Tom", 28)):构造临时Person → 移动构造到vector → 析构临时对象;
  • emplace_back("Tom", 28):直接在vector中构造Person,仅1次构造,无额外开销。

2. 简单类型(int/float/string)

对于int、float等内置类型,或string等支持移动语义的简单类型,两者性能几乎无差异:

vector<int>vec;vec.push_back(10);// 直接拷贝int,无开销vec.emplace_back(20);// 原地构造int,无开销// 两者效率完全一致

3. 例外场景:插入已有对象

若插入的是已存在的对象push_backemplace_back均需拷贝,性能无差异:

Personp("Dave",35);vec.push_back(p);// 拷贝构造vec.emplace_back(p);// 拷贝构造(等价于push_back)

四、易错点与使用建议

1. 易错点:emplace_back并非“万能更优”

  • 若传入的是已有对象(而非构造参数),emplace_back会退化为拷贝构造,与push_back无区别;
  • emplace_back可能调用隐式构造函数,若类的单参数构造函数加了explicit,会编译报错(push_back同理):
    classTest{public:explicitTest(inta){}// explicit禁止隐式转换};vector<Test>vec;// vec.emplace_back(10); // 合法:直接调用显式构造// vec.push_back(10); // 编译报错:10无法隐式转为Test

2. 使用建议

  • 优先用emplace_back:C++11及以后,除插入已有对象外,均推荐使用emplace_back,兼顾性能和简洁性;
  • push_back场景:插入已存在的对象(如vec.push_back(existing_obj)),语义更清晰;
  • 注意兼容性:若代码需兼容C++03,只能用push_back

五、底层实现简化对比

// push_back的简化实现(核心逻辑)template<classT>voidvector<T>::push_back(constT&val){// 1. 扩容(若需要)reserve(size()+1);// 2. 拷贝构造到尾部new(data()+size())T(val);// 定位new(拷贝)size++;}// emplace_back的简化实现(核心逻辑)template<classT,class...Args>voidvector<T>::emplace_back(Args&&...args){// 1. 扩容(若需要)reserve(size()+1);// 2. 原地构造(完美转发参数)new(data()+size())T(std::forward<Args>(args)...);// 定位new(直接构造)size++;}

核心差异:push_back先构造/拷贝对象,再传入;emplace_back直接将构造参数传给定位new,原地构造。

总结(核心要点回顾)

  1. 核心差异push_back插入“已构造的对象”(有拷贝/移动开销),emplace_back接收“构造参数”原地构造(无临时对象);
  2. 性能:自定义类型(多参数构造)下emplace_back更优,简单类型/已有对象两者无差异;
  3. 使用原则:C++11+优先用emplace_back,插入已有对象时push_back语义更清晰。

emplace_back是C++对“零开销抽象”的典型实现,既保持了代码简洁性,又消除了不必要的临时对象开销,是vector添加元素的首选接口。

http://www.jsqmd.com/news/500487/

相关文章:

  • 金诺爱美汇科技美容有限公司知名度高吗,在本地提供哪些受欢迎的美容服务? - myqiye
  • 激光摆动焊接的Abaqus温度场分析:探索多种热源与摆动模式
  • 想一次搞定多本软著?亲测有效的申请攻略来啦!
  • 2026年百联卡如何回收,带你解锁三种有效方法 - 京回收小程序
  • 理解LangChain的结构化输出
  • 探寻山西优质观察井厂,口碑好的制造商排名 - 工业设备
  • Avalonia的生命周期 之二
  • 微搭低代码MBA培训管理系统16——商机管理
  • 英伟达 GTC 2026:黄仁勋为何认为每家公司都需要智能体人工智能战略
  • 上海凯茸包装加码安全新赛道:B1级阻燃瓦楞纸投产,构建全场景防护矩阵 - 博客万
  • OpenClaw 腾讯云服务本地访问配置指南
  • 国内首个,面向中小企业数据资产估值体系:“荟宸信科面向中小企业数据资产估值体系”正式发布(二)
  • 2026年电商仓库用大盘纸十大厂家排名,浩月职业纸业上榜 - 工业品网
  • 2026年铜陵市企业搬迁与家庭搬家服务市场主流服务商综合评估指南 - 2026年企业推荐榜
  • 个性化定制+移动应用,ERP系统新玩法的魅力你知道吗?
  • Avalonia的生命周期 之四
  • C语言教程——运算符
  • 2026年执业药师刷题app深度测评:6款热门工具对比,选对少走3个月弯路 - 孤篇横绝
  • 工程师AI工具使用笔记:高效研发辅助技巧
  • SkyReels-Text:Fine-grained Font-Controllable Text Editing for Poster Design
  • 石蜡切片 VS 冰冻切片:一文读懂两者的核心差异与选择策略
  • AI生成课程论文靠谱吗?实测12款一键生成论文的软件教程,效率翻倍告别熬夜! - 掌桥科研-AI论文写作
  • 2026年执业药师备考刷题APP深度测评:6款主流工具优势解析,帮你选对提分神器 - 孤篇横绝
  • Keysight E4990A阻抗分析仪MLCC陶瓷电容器介电温谱测试
  • VUE + 操作系统的生命周期的庖丁解牛
  • 2026年无锡劳动工伤律师团队深度盘点:如何选择与联系专业维权伙伴? - 2026年企业推荐榜
  • java基于springboot微信小程序的大学生心理音乐治疗的设计与实现
  • 【2026年-11期】Where lies the future of humanity in the age of AI?
  • 阿里云AI算力服务涨价,背后原因与市场影响几何?
  • 开服即被打瘫痪?湘情盾:让攻击者“找不着北”,这次新服稳了!