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

时间: 2024-10-03 16:43:10

C++11中emplace_back和push_back比较的相关文章

C++11使用emplace_back代替push_back

最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 首先,写了一个类用于计时, //time_interval.h #pragma once #include <iostream> #include <memory> #include <string> #ifdef GCC #include <sys/time.h> #

c++11 vector使用emplace_back代替push_back

C++11中,针对顺序容器(如vector.deque.list),新标准引入了三个新成员:emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分别对应push_front.insert和push_back,允许我们将元素放置在容器头部.一个指定位置之前或容器尾部. 当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中.而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数.em

学习 emplace_back() 和 push_back 的区别 emplace_back效率高

在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中.原来的临时变量释放.这样造成的问题是临时变量申请的资源就浪费. c++11引入了右值引用,转移构造函数(请看这里)后,push_back()右值时就会调用构造函数和转移构造函数. 在这上面有进一步优化的空间就是使用emplace_back emplace_back   在容器尾部添加一个元

【转载】C++ 11中的右值引用

本篇随笔为转载,原博地址如下:http://www.cnblogs.com/TianFang/archive/2013/01/26/2878356.html 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream>    #include <vector>    using namespace std; class obj    {    public :        obj() { cout <&l

C++ 11 中的右值引用

C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream>    #include <vector>    using namespace std; class obj    {    public :        obj() { cout << ">> create obj " << endl; }        obj(c

emplace_back与push_back的区别

std::vector::emplace_back C++ Containers library std::vector template< class... Args >void emplace_back( Args&&... args );   (since C++11)       Appends a new element to the end of the container. The element is constructed in-place, i.e. no

C++11中的变量初始化

变量初始化很简单嘛,有什么难的? 打住,不要骄傲,往下看,你会哭的. 请看下面四个问题: 1: 下面的语句有不同吗?不同在哪里? widget w;                   // a widget w();                 // b widget w{};                 // c widget w(x);                // d widget w{x};                // e widget w = x;       

(译)C++11中的Move语义和右值引用

郑重声明:本文是笔者网上翻译原文,部分有做添加说明,所有权归原文作者! 地址:http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html C++一直致力于生成快速的程序.不幸的是,直到C++11之前,这里一直有一个降低C++程序速度的顽症:临时变量的创建.有时这些临时变量可以被编译器优化(例如返回值优化),但是这并不总是可行的,通常这会导致高昂的对象复制成本.我说的是怎么回事呢? 让我们

C++学习笔记18,C++11中的初始化列表构造函数(二)

C++11中的初始化列表构造函数(Initialize_list Constructors)是将std::initializer_list<T>作为第一个参数的构造函数,并且没有任何其他参数(或者其他参数具有默认值).例如: #include <iostream> #include <initializer_list>//必须包含该头文件 #include <vector> using namespace std; class A { private: ve