C++11中emplace_back和push_back比较
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 class A 6 { 7 public: 8 A(int a) 9 :m_a(a) 10 {//构造函数 11 cout<<"A()"<<endl; 12 } 13 A(const A& a) 14 :m_a(a.m_a) 15 {//拷贝构造函数 16 m_count++; 17 cout<<"A(const A& a) "<< "m_count " << m_count <<endl; 18 } 19 const A& operator = (const A&a) 20 {//赋值构造函数 21 this->m_a = a.m_a; 22 return *this; 23 } 24 public: 25 static int m_count; 26 private: 27 int m_a; 28 }; 29 30 int A::m_count = 0; 31 32 int main() 33 { 34 A a(1); //定义对象a,调用构造函数 35 A b = a; //定义对象b,并用a进行初始化,调用拷贝构造函数 36 b = a; //赋值操作 调用重载的赋值运算符 37 cout<<"================"<<endl; 38 A::m_count = 0; 39 vector<A> aVec(10,1); //调用一次构造函数,之后进行了10次的拷贝构造 40 cout<< "aVec.capacity(): " <<aVec.capacity()<<endl; //此时aVec的实际空间大小为10 41 cout<<"================"<<endl; 42 A::m_count = 0; 43 aVec.push_back(A(1)); //调用一次构造函数和一次拷贝构造函数,但是vector占用的实际内存空间发生了再分配,拷贝原有的元素,因此会再调用10次拷贝构造函数 44 cout<< aVec.capacity()<<endl; //此时aVec的实际空间大小为20,vector实际占用的内存成倍的增长 45 cout<<"================"<<endl; 46 aVec.emplace_back(1); //此时内存空间已经增长完毕,调用emplace_back只调用一次构造函数,即直接在vector的内存空间中构造元素,而没有发生拷贝.这也是emplace_back比push_back高效的原因. 47 cout<<"aVec.capacity(): "<< aVec.capacity()<<endl; 48 cout<<"================"<<endl; 49 50 return 0; 51 }
代码输出:
1 A() 2 A(const A& a) m_count 1 3 ================ 4 A() 5 A(const A& a) m_count 1 6 A(const A& a) m_count 2 7 A(const A& a) m_count 3 8 A(const A& a) m_count 4 9 A(const A& a) m_count 5 10 A(const A& a) m_count 6 11 A(const A& a) m_count 7 12 A(const A& a) m_count 8 13 A(const A& a) m_count 9 14 A(const A& a) m_count 10 15 aVec.capacity(): 10 16 ================ 17 A() 18 A(const A& a) m_count 1 19 A(const A& a) m_count 2 20 A(const A& a) m_count 3 21 A(const A& a) m_count 4 22 A(const A& a) m_count 5 23 A(const A& a) m_count 6 24 A(const A& a) m_count 7 25 A(const A& a) m_count 8 26 A(const A& a) m_count 9 27 A(const A& a) m_count 10 28 A(const A& a) m_count 11 29 20 30 ================ 31 A() 32 aVec.capacity(): 20 33 ================
从以上代码中可以清晰地看到在容器上调用emplace_back和push_back的区别以及vector内存的动态增长过程.
参考资料:C++Primer 第五版