C++ STL 容器vector添加元素函数emplace_back()和push_back()的使用差异及比较

1、vector容器的特点

vector底层数据结构是一个动态数组,就是在实例化一个vector对象时,如果不手动对其容量进行设置的话,vector的默认容量为0,即capacity()返回值为0。随着向容器中添加元素,容器对象按照1 2 4 8 16 32 二倍扩容。GCC是按照二倍扩容,VS13是1.5倍扩容。

扩容后是一段新的内存空间,此时就需要将旧的内存空间里的所有元素拷贝到新的内存空间中去(如果元素为一个类的对象的话,此时会触发拷贝构造函数),然后再在新的内存空间中的原数据元素后面继续插入新的元素,且旧的内存空间会被释放,如果元素为一个类的对象的话,则会触发析构函数

2 测试方法

因此,在测试emplace_back()和push_back()函数时,需要对容器进行分配初始容量,避免多次多次插入触发扩容,影响测试效果。可以使用vector的成员函数reserve()初始化容器容量。

push_back()和emplace_back()函数的主要区别在于两个函数的底层实现机制不同。push_back()函数在向容器末尾添加新元素时,会先创建该元素,然后再将该元素移动或者拷贝到容器中;emplace_back()函数的底层实现是直接在容器尾部创建该新元素,不存在拷贝或者移动元素的过程。
为了更好的阐述两者的区别,来编写一个实现了构造函数、拷贝构造、移动构造的类,使用该类的对象作为元素插入容器,来查看具体区别,示例代码如下:

#include <iostream>
#include <vector>
// #include <unistd.h>

using namespace std;
class CPPTest{
  public:
    CPPTest(int num) : m_pNum(num) { 
      cout << "执行构造函数 ,m_pNum = " << m_pNum << " ! " << endl; 
    };
    CPPTest(const CPPTest& obj) : m_pNum(obj.m_pNum) {
      cout << "执行拷贝构造函数 ,m_pNum = "  << m_pNum << " ! " << endl;
    };
    CPPTest(const CPPTest&& obj) : m_pNum(obj.m_pNum) {
      cout << "执行移动构造函数 ,m_pNum = " << m_pNum << " ! " << endl;
    };

    ~CPPTest() {
      cout << "执行析构函数 ,m_pNum = " << m_pNum << " ! "<< endl;
    }

  private:
    int m_pNum;
};

int main(int argc, char *argv[]) {
  
  vector<CPPTest> pVec;
  //初始化容器的容量,如果不对容器进行初始化,则容器的容量初始值为0,之后随着增加元素,容量为按照2倍的形式增长。即0、1、2、4...
  //在此过程中,容器再重新分配空间时,会出发元素的拷贝函数,影响比对效果。
  //在此,利用reserve函数初始化容器容量为5.
  pVec.reserve(5); 

  cout << "emplace_back  function execute!" << endl;
  pVec.emplace_back(1);
  cout << endl;
  cout << "push_back function execute!" << endl;
  pVec.push_back(2); 
  cout << endl;
  // pause();
  return 0;
}

编译运行的结果如下:

emplace_back  function execute!
执行构造函数 ,m_pNum = 1 ! 

push_back function execute!
执行构造函数 ,m_pNum = 2 ! 
执行移动构造函数 ,m_pNum = 2 ! 
执行析构函数 ,m_pNum = 2 ! 

执行析构函数 ,m_pNum = 1 ! 
执行析构函数 ,m_pNum = 2 !

3 比较结果

从运行结果输出来看,push_back() 底层实现时,优先选择调用移动构造函数,如果类中没有实现移动构造函数,则调用拷贝构造函数。

从以上分析可以得出结论,emplace_back函数和push_back函数在效率方面相比,emplace_back函数较优。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值