C++ push_back和emplace_back的区别(含测试代码)

#include<iostream>
#include<string>
#include<set>
#include<time.h>
#include<cstring>
#include <vector>
#define LL long long
#define MAXN 100010
using namespace std;
int tot=0;

class A {
private:
    int lima;
    int limb;
    int las=tot;
public:
    A(){las=++tot;lima = 1;limb =12 ;cout<<las<<" A created;"<<endl;}
    //explicit A(int a,int b):lima(a),limb(b){las=++tot;cout<<las<<" A common created"<<endl;}     会使得参数列表失效
    A(int a,int b):lima(a),limb(b){las=++tot;cout<<las<<" A common created"<<endl;}
    A(A&& a){las=++tot;lima = a.lima; limb = a.limb;cout<<las<<" A move created"<<endl;}
    A(const A& a){las=++tot;lima = a.lima;limb = a.limb; cout<<las<<" A copy created"<<endl;}
    ~A(){cout<<las<<" A deleted"<<endl;};
};


inline A liss(int lim1,int lim2)
{
    A limp(lim1,lim2);
    return limp;
}

vector<A>vec;

int main()
{
    //A lim(12,15);
    vec.reserve(20);                    /*把这个打开,防止扩容机制造成的拷贝构造结果混乱*/
    //vec.push_back(lim);
    //vec.emplace_back(lim);
    //cout<<"where delete?"<<endl;
    /*观察结果:过程相同,都调用拷贝构造函数直接深拷贝构造,原因:传入参数都为左值*/
    
    //vec.push_back(A(lim));
    //vec.emplace_back(A(lim));
    //cout<<"where delete?"<<endl;
    /*观察结果:过程一样,都产生临时变量并且调用移动构造函数,和网上说的不一样,推测函数返回值可能有问题,以下再次验证*/
    
    //vec.push_back(liss(125,133));
    //vec.emplace_back(liss(125,153));
    //cout<<"where delete?"<<endl;
    /*观察结果:过程一样,都产生临时变量并且调用移动构造函数,和网上说的不一样,查询原码发现,部分编译器对于单个右值返回,pushback会使用右值引用接住后再次使用move转为右值并调用emplaceback*/

    //vec.push_back({158,957});
    //vec.emplace_back(158,957);
    //cout<<"where delete?"<<endl;

    /*观察结果:
    1 A common created
    2 A move created
    1 A deleted
    3 A common created
    where delete?
    2 A deleted
    3 A deleted
    这就意味着对于传入右值参数的情况,push_back会先直接构造一个类,然后调用移动构造函数将类移动到vec末尾
    而emplace_back会直接在末尾构造这个类

    注意有的编译器会产生优化,单个右值传入的情况编译器会直接优化为emplaceback执行
    而参数列表能够明显的看出区别,和网上所说一致,实验成功
    */

    //int a1=147,b1=254;
    //vec.push_back({a1,b1});
    //vec.emplace_back(a1,b1);
    //cout<<"where delete?"<<endl;
    /*观察结果:
    1 A common created
    2 A move created
    1 A deleted
    3 A common created
    where delete?
    2 A deleted
    3 A deleted
    这就意味着对于传入左值参数的情况,和上面是一样的
    */
    return 0;
}

 

posted @ 2023-04-19 22:05  ztlsw  阅读(25)  评论(0编辑  收藏  举报