首页 > 编程语言 >C++标准库vector 的push_back和emplace_back有什么区别?

C++标准库vector 的push_back和emplace_back有什么区别?

时间:2025-01-14 12:29:59浏览次数:3  
标签:std emplace cout back C++ vec push

以下是对 vectorpush_backemplace_back 方法的详细解释:

一、push_back 方法

  • 功能

    • push_backstd::vector 类的成员函数,用于在向量的末尾添加元素。
    • 当使用 push_back 时,会将元素的副本添加到向量的末尾。
  • 使用示例

#include <iostream>
#include <vector>


class MyClass {
public:
    MyClass() {
        std::cout << "Default constructor" << std::endl;
    }


    MyClass(const MyClass& other) {
        std::cout << "Copy constructor" << std::endl;
    }


    MyClass(MyClass&& other) {
        std::cout << "Move constructor" << std::endl;
    }


    ~MyClass() {
        std::cout << "Destructor" << std::endl;
    }
};


int main() {
    std::vector<MyClass> vec;


    MyClass obj;


    // 使用 push_back 添加元素
    vec.push_back(obj);


    return 0;
}
  • 代码解释
    • 当调用 vec.push_back(obj); 时,会发生以下步骤:
      1. 调用 MyClass 的复制构造函数,将 obj 的副本添加到 vec 的末尾。
      2. 如果 MyClass 支持移动语义(即提供了移动构造函数),编译器可能会调用移动构造函数进行优化,以避免不必要的复制。

二、emplace_back 方法

  • 功能

    • emplace_back 也是 std::vector 的成员函数,用于在向量的末尾直接构造元素。
    • 它通过 std::forward 将参数完美转发给元素的构造函数,避免了额外的复制或移动操作,在适当情况下可以提高性能。
  • 使用示例

#include <iostream>
#include <vector>


class MyClass {
public:
    MyClass() {
        std::cout << "Default constructor" << std::endl;
    }


    MyClass(const MyClass& other) {
        std::cout << "Copy constructor" << std::endl;
    }


    MyClass(MyClass&& other) {
        std::cout << "Move constructor" << std::endl;
    }


    ~MyClass() {
        std::cout << "Destructor" << std::endl;
    }


    MyClass(int x, int y) {
        std::cout << "Custom constructor with arguments " << x << " and " << y << std::endl;
    }
};


int main() {
    std::vector<MyClass> vec;


    // 使用 emplace_back 直接在向量末尾构造元素
    vec.emplace_back(1, 2);


    return 0;
}
  • 代码解释
    • 当调用 vec.emplace_back(1, 2); 时,会发生以下步骤:
      1. 直接在 vec 的末尾调用 MyClass 的构造函数,使用 12 作为参数构造元素,而不是先创建对象,再复制或移动到向量中。

三、性能比较

  • push_backemplace_back 的性能对比
    • 对于简单类型(如 intdouble 等),两者性能差异可能不明显,因为复制或移动的成本较低。
    • 对于复杂类型(如自定义类),emplace_back 可能更优,尤其是当类的复制或移动成本较高时。

四、使用建议

  • 何时使用 push_back

    • 当你已经有一个对象,并且想要将其副本添加到向量末尾时,可以使用 push_back
  • 何时使用 emplace_back

    • 当你想在向量末尾直接构造元素,并且元素的构造函数可以接受所需的参数时,使用 emplace_back 可以避免额外的复制或移动操作,提高性能。

以下是一个综合使用 push_backemplace_back 的示例:

#include <iostream>
#include <vector>


class MyClass {
public:
    MyClass(int x) : data(x) {
        std::cout << "Constructor with parameter: " << data << std::endl;
    }


    MyClass(const MyClass& other) : data(other.data) {
        std::cout << "Copy constructor" << std::endl;
    }


    MyClass(MyClass&& other) : data(std::move(other.data)) {
        std::cout << "Move constructor" << std::endl;
    }


    ~MyClass() {
        std::cout << "Destructor for " << data << std::endl;
    }


    int data;
};


int main() {
    std::vector<MyClass> vec;


    MyClass obj1(1);


    // 使用 push_back 添加对象的副本
    vec.push_back(obj1);


    // 使用 emplace_back 直接在向量末尾构造元素
    vec.emplace_back(2);


    return 0;
}

总结

  • push_back 主要用于将现有对象的副本或移动对象添加到向量末尾,可能会调用复制或移动构造函数。
  • emplace_back 用于在向量末尾直接构造元素,避免了额外的复制或移动操作,通过完美转发参数给元素的构造函数。
  • 在性能敏感的代码中,尤其是处理复杂类型时,优先考虑使用 emplace_back 可以提高性能。

需要注意的是,使用 emplace_back 时,需要确保元素的构造函数可以接受提供的参数,并且在某些情况下,编译器可能会自动优化 push_back 的性能,使其与 emplace_back 接近。

标签:std,emplace,cout,back,C++,vec,push
From: https://blog.csdn.net/qq_15258067/article/details/145106354

相关文章

  • 【C++指南】模板 深度解析
         ......
  • 【HarmonyOS NAPI 深度探索4】安装开发环境(Node.js、C++ 编译器、node-gyp)
    【HarmonyOSNAPI深度探索4】安装开发环境(Node.js、C++编译器、node-gyp)要使用N-API开发原生模块,第一步就是配置好开发环境。虽然HarmonyOSNext中提供了DevEco-Studio一站式IDE,可以直接帮助我们完成开发环境的搭建,但是为了更深入的了解NAPI,我们用最原始的编译工具一步......
  • C++中线程同步与互斥的4种方式介绍、对比、场景举例
    在C++中,当两个或更多的线程需要访问共享数据时,就会出现线程安全问题。这是因为,如果没有适当的同步机制,一个线程可能在另一个线程还没有完成对数据的修改就开始访问数据,这将导致数据的不一致性和程序的不可预测性。为了解决这个问题,C++提供了多种线程同步和互斥的机制。1.......
  • 【C++17 library features】深入解析 C++17 标准库中的文件系统 (std::filesystem)
    目录标题第一章:std::filesystem概述1.1C++17引入文件系统库的背景和动机1.2std::filesystem的主要功能和模块结构1.2.1路径管理(PathManagement)1.2.2文件和目录操作(FileandDirectoryOperations)1.2.3文件属性与状态(FileAttributesandStatus)1.2.4错误处理......
  • Xtrabackup备份与恢复
    Xtrabackup是一个对Mysql做数据备份的工具,支持在线热备份(备份时不影响数据读写),Xtrabackup有两个主要的工具:xtrabackup、innobackupex,其中innobackupex已经逐渐被xtrabackup取代 特点: (1)备份过程快速、可靠; (2)备份过程不会打断正在执行的事务; (3)能够基于压缩等功能节约磁......
  • VScode搭建opencv环境c++,这个是我发的压缩包里面的
    通过网盘分享的文件:D.zip等2个文件链接:https://pan.baidu.com/s/1qiU3rgd4did84F83d3yKnQ提取码:npkg这里面的新建文件夹是软件,不用管D代表配置文件,里面的代码要改路径D里面有两个文件夹,一个是.vscode,里面的文件代码要改,后文会讲到一个是Debugger,这个不要管还有......
  • C++中获取随机数的几种方法
    1.C++中获取随机数的几种方法1.1随机数基本概念:随机数:在一定范围内[a,z],每个数出现的概率相等并且无法预测下一个数的数值序列。伪随机数生成器(PRNG)原理:由一个状态寄存器和一个更新函数组成,初始状态由种子决定,更新状态会根据当前状态生成下一个状态,并输出一个伪随机......
  • 【最新原创毕设】基于SSM的在线学习平台+09650(免费领源码)可做计算机毕业设计JAVA、PHP
    目 录摘要1绪论1.1选题背景及意义1.2国内外现状分析1.3论文结构与章节安排2 在线学习平台系统分析2.1可行性分析2.2系统业务流程分析2.3系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4系统用例分析2.5本章小结3在线学习平台总体设......
  • C++:指针、类型指针与引用,一文全掌握!
    在C++语言中,指针类型、类型指针及引用是三个密切相关而又各有特点的概念。理解它们之间的区别和联系对于掌握C++的内存管理和编程技巧至关重要。本文将深入探讨这些概念,帮助读者更好地理解它们在C++中的使用和重要性。一、指针类型与类型指针的区别在C++中,指针类型的定义涉......
  • C++:string
    一、string概念之前介绍过通过字符数组保存字符串,然后对字符数组中的字符串做各种操作;为了更加简单方便,在C++中,又增加了string来处理字符串。charstr[20]="helloworld";string字符串其实是一种更加高级的封装,string字符串中包含大量的方法,这些方法使得......