c++ push_back()和emplace_back()区别
c++ push_back()和emplace_back()区别
一、区别:
都可以直接根据传入的参数选择匹配的构造函数隐式构造对象。
但隐式构造时:
1. push_back()
-
如果未定义移动构造函数,传入到push_back()的参数与元素对应类的某个构造函数匹配,那么会隐式构造一个元素,首先调用构造函数构造临时对象,然后调用拷贝构造函数讲这个临时对象放入容器中。
-
如果定义了移动构造函数,上述过程就会变成依次调用构造函数和移动构造函数。
2. emplace_back()
- 在容器尾部添加一个元素, 传入到emplace_back()的参数与元素对应类的某个构造函数匹配, 这个元素原地构造对象,仅需要调用构造函数, 而不会调用拷贝构造函数或移动构造函数。
3. 程序示例
#include
#include
using namespace std;
class Foo{
private:
int a;
public:
Foo(int num): a(num) {
cout<<"Foo Constructor "< vec1;
vec1.push_back(1);
cout< vec2;
vec2.emplace_back(2);
vec2.emplace_back(3);
}
输出:
push_back:
Foo Constructor 1
move constructor //若注释掉移动构造函数,此处将调用拷贝构造函数
Foo Destructor...
emplace_back:
Foo Constructor 2
Foo Constructor 3
copy constructor //vec2扩容后,拷贝元素到新空间
Foo Destructor... //vec2扩容后,旧空间中的元素析构
Foo Destructor... //vec1中的元素析构
Foo Destructor... //vec2中的元素析构
Foo Destructor... //vec2中的元素析构
4. 疑问:为什么emplace_back:后,打印了一次拷贝构造函数,以及四次析构函数?
https://blog.csdn.net/luomoshusheng/article/details/48226517
因为定义的vector初始容量为0,加入一个元素容量扩容为1,再加入一个元素,分配新空间扩容为2,vector中元素要拷贝到新空间,旧元素销毁。
二、相同之处
- 拷贝构造函数和移动构造函数均已定义,push_back/emplace_back向容器中加入左值元素,均将调用构造函数和拷贝构造函数拷贝对象加入到容器中。
#include
#include
using namespace std;
class Foo{
private:
int a;
public:
Foo(int num): a(num) {
cout<<"Foo Constructor "< vec1;
Foo foo1(1);
vec1.push_back(foo1);
cout<<1< vec2;
Foo foo2(2);
vec2.emplace_back(foo2);
cout<<2<
push_back:
Foo Constructor 1
copy constructor
1
emplace_back:
Foo Constructor 2
copy constructor
2
Foo Destructor...
Foo Destructor...
Foo Destructor...
Foo Destructor...
- 拷贝构造函数和移动构造函数均定义,push_back/emplace_back向容器中加入显式构造的右值元素, 那么均会先后调用构造函数和移动构造函数,再加入到容器中。
#include
#include
using namespace std;
class Foo{
private:
int a;
public:
Foo(int num): a(num) {
cout<<"Foo Constructor "< vec1;
vec1.push_back(Foo(1));
cout<<1< vec2;
vec2.emplace_back(Foo(2));
cout<<2<
push_back:
Foo Constructor 1
move constructor
Foo Destructor...
1
emplace_back:
Foo Constructor 2
move constructor
Foo Destructor...
2
Foo Destructor...
Foo Destructor...