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 第五版