多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

C++ emplace_back 与 push_back 详解

C++ emplace_back 与 push_back 详解 一、核心区别对比项push_backemplace_back参数接受一个已存在的对象接受构造函数的参数过程先构造对象再拷贝到容器直接在容器中构造对象效率可能产生临时对象和拷贝零拷贝最高效一句话总结push_back是“插入对象”emplace_back是“就地构造”。二、代码示例对比2.1 基础演示cpp #include iostream #include vector #include string using namespace std; class Student { public: string name; int age; Student(string n, int a) : name(n), age(a) { cout 构造: name endl; } Student(const Student other) : name(other.name), age(other.age) { cout 拷贝构造: name endl; } }; int main() { vectorStudent students; // push_back先构造临时对象再拷贝到容器 cout push_back endl; students.push_back(Student(Alice, 20)); // 输出构造: Alice // 输出拷贝构造: Alice // emplace_back直接在容器中构造无拷贝 cout \n emplace_back endl; students.emplace_back(Bob, 22); // 输出构造: Bob return 0; }2.2 实际应用场景cpp #include vector #include string #include map using namespace std; int main() { // 场景1添加简单类型 vectorint nums; nums.push_back(10); // OK nums.emplace_back(20); // 也可以 // 场景2构造pair推荐emplace_back vectorpairstring, int pairs; pairs.emplace_back(key, 42); // 直接传参高效 pairs.push_back({key, 42}); // 需要花括号构造临时对象 // 场景3复杂对象emplace_back优势明显 vectormapstring, vectorint complexVec; complexVec.emplace_back(); // 构造空map // complexVec.push_back({}); // 也行但会多一次拷贝 // 场景4不可拷贝类型只能用emplace_back vectorunique_ptrint ptrs; ptrs.emplace_back(new int(42)); // OK // ptrs.push_back(new int(42)); // 错误unique_ptr不可拷贝 return 0; }三、使用建议3.1 优先使用 emplace_back 的场景cpp // 1. 需要临时构造对象最常见 vectorstring strs; strs.emplace_back(hello); // 推荐 strs.push_back(hello); // 会产生临时对象 // 2. 多参数构造 struct Point { int x, y; }; vectorPoint points; points.emplace_back(3, 4); // 直接传两个参数 points.push_back({3, 4}); // 需要花括号 // 3. 复杂类型构造 vectorvectorint matrix; matrix.emplace_back(5, 10); // 构造包含10个5的vector matrix.push_back({5, 10}); // 构造包含5和10的vector含义不同3.2 使用 push_back 的场景cpp // 1. 添加已存在的对象语义更清晰 string existing world; vec.push_back(existing); // 明确是拷贝 vec.emplace_back(existing); // 也能工作但push_back更直观 // 2. 使用移动语义时 vec.push_back(std::move(existing)); // 明确表示移动 vec.emplace_back(std::move(existing)); // 也可以四、总结使用场景推荐方法原因临时构造新对象emplace_back避免临时对象效率更高添加已存在的对象push_back语义清晰代码可读性好多参数构造emplace_back代码更简洁不可拷贝类型emplace_back必须使用最佳实践在大多数情况下优先使用emplace_back它更通用且高效。只有在明确需要表达“插入一个已存在的对象”时才使用push_back。
返回列表