卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

  • STL 与容器

    • STL容器了解哪些
    • STL中allocator的作用
    • STL中迭代器失效的场景
    • c++的map和unordered_map有什么区别和实现原理
    • map,deque,list的底层实现原理
    • unordered_map的rehash机制
    • vector底层原理和扩容过程
    • push_back()和emplace_back()的区别
      • 简要回答
      • 详细回答
      • 适用场景
      • 代码示例
      • 知识拓展
  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# push_back()和emplace_back()的区别

# 简要回答

push_back() 在容器尾部添加元素时,会先构造一个临时对象,然后通过拷贝或移动构造函数将其添加到容器中。

emplace_back() 直接在容器尾部构造元素,避免了临时对象的创建,通常更高效。

就是说push_back()在容器外面做东西,做好后在放进容器中;emplace_back()直接在容器里面做,省去放入这个动作,因此更高效。

# 详细回答

  1. 构造方式:

push_back():接受一个已构造的对象(左值或右值),通过拷贝或移动操作将其添加到容器

emplace_back():接受构造参数,直接在容器内存中构造对象

  1. 效率:

push_back() 可能涉及临时对象构造和拷贝/移动操作

emplace_back() 通常只需一次构造,避免了不必要的拷贝/移动

  1. 参数传递:

push_back() 只能接受单一对象参数

emplace_back() 可以接受多个参数,直接转发给构造函数

  1. 异常安全:

emplace_back() 在某些情况下可能提供更强的异常安全保证

# 适用场景

场景 推荐函数 原因
需要传入现有对象 push_back() 你已经有了一个对象,直接推入即可
构造临时对象时 emplace_back() 直接构造,无需中间变量
追求性能、避免拷贝开销 emplace_back() 节省资源,构造效率更高
容器中元素构造参数较复杂 emplace_back() 支持多参数构造,避免不必要的中间对象

# 代码示例

#include <vector>
#include <string>

class Person {
public:
    Person(std::string name, int age) : name_(std::move(name)), age_(age) {
        std::cout << "构造 Person: " << name_ << "\n";
    }

    Person(const Person& other) : name_(other.name_), age_(other.age_) {
        std::cout << "拷贝 Person: " << name_ << "\n";
    }

    Person(Person&& other) noexcept : name_(std::move(other.name_)), age_(other.age_) {
        std::cout << "移动 Person: " << name_ << "\n";
    }

private:
    std::string name_;
    int age_;
};

int main() {
    std::vector<Person> people;

    // push_back 示例
    Person p1("Alice", 30);
    people.push_back(p1);  // 拷贝构造
    people.push_back(Person("Bob", 25));  // 构造临时对象 + 移动构造

    // emplace_back 示例
    people.emplace_back("Charlie", 40);  // 直接构造
    people.emplace_back(std::string("David"), 35);  // 直接构造

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 知识拓展

  • 知识图解 image
  • 面试官可能追问
  1. 在什么情况下 push_back() 可能比 emplace_back() 更高效?

当对象移动操作比构造更高效时

当已有现成对象且构造代价高于移动时

  1. 为什么 emplace_back() 有时会导致代码更难理解?

因为它可以接受构造参数,可能需要查看类定义才能知道实际构造的对象类型

  1. 如何决定使用哪种方法?

遵循"有现成用 push,需要构造用 emplace"原则

考虑性能关键路径和代码可读性的平衡

  1. emplace_back() 是否总是避免拷贝/移动?

不总是,如果vector需要扩容,元素仍然需要移动

Last Updated: 3/10/2026, 6:08:48 PM

← vector底层原理和扩容过程 C++内存分区,堆和栈的区别 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪