vector中push_back和emplace_back区别
vector中push_back和emplace_back区别
正常情况下push_back是往vector中添加新的元素,只不过添加过程是先利用拷贝构造函数复制目标值,而 emplace_back可以 直接在目标位置上生成对象,这也正式emplace的原本放置的意思。
具体在使用上,如果push的对象元素是已经生成好了的(如Nelson),emplace_back和push_back可以认为没有区别,如果原本没有要push的这个元素,则直接原地生成效率较高;
实际在push的时候,由于vector内存需要连续,在vector size达到1, 2,4,8…时其长度需要自动增加,故四二次push时首先生成目标元素,检测到现有存储空间已满,会调用复制构造函数来重头到尾复制前面的vector元素,依次push进去vector之后再析构掉复制的元素,最后再将目标元素push进去;
一般移动构造函数的输入为右值,操作完成后右值内容就为空了(数字除外),具体过程可由std::move(左值) 进行模仿.
如果传入的为右值但没有定义移动构造函数,则可调用拷贝构造函数。即emplace_back和push_back均可接收左值(普通变量)和右值(无名临时对象),左值调用复制构造函数,右值调用移动构造函数,表现一致;
President joy("joy ", "USA", 2021);
elections.emplace_back(std::move(joy));
elections.emplace_back(std::move(joy));
elections.emplace_back(std::move(joy));
//输出结果
joy elected president of USA in 2021.
elected president of in 2021.
elected president of in 2021.
emplace_back结果
elections.emplace_back(“Nelson Mandela”, “South Africa”, 1994)
I am being constructed.
elections.emplace_back(Nelson);
I am being constructed.
I am being copy constructed.
moved:
joy USA2021
elections.emplace_back(std::move(Nelson));
I am being constructed.
I am being moved.
moved:
2021
push_back结果
reElections.push_back(President(“Franklin Delano Roosevelt”, “the USA”, 1936))
I am being constructed.
I am being moved.
I am being destructed.
reElections.push_back(obama);
I am being constructed.
I am being copy constructed.
moved:
Franklin USA1966
reElections.push_back(std::move(obama));
I am being constructed.
I am being moved.
moved:
1966
区别测试代码
这里是参考博客 ()
.
// An highlighted block
#include <vector>
#include <string>
#include <iostream>
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year) //构造函数
:name(p_name), country(p_country), year(p_year)
{ std::cout << "I am being constructed.\n"; }
President(const President& other) //拷贝构造函数
:name(other.name), country(other.country), year(other.year)
{ std::cout << "I am being copy constructed.\n";}
President(President&& other) //移动构造函数
:name(std::move(other.name)), country(std::move(other.country)), year(other.year)
{ std::cout << "I am being moved.\n"; }
President& operator=(const President& other);
~President()
{ std::cout << "I am being destructed.\n";}
};
int main()
{
std::vector<President> elections;
std::cout << "emplace_back:\n";
elections.emplace_back("Nelson ", "frica", 1994); //没有类的移动
elections.emplace_back("Nelson ", "Africa", 1995);
elections.emplace_back("Nelson ", "Africa", 1996);
President joy("joy ", "USA", 2021);
elections.emplace_back(std::move(joy));
std::vector<President> reElections;
std::cout << "\npush_back:\n";
reElections.push_back(President("Franklin ", "USA", 1936));
reElections.push_back(President("Franklin ", "USA", 1937));
reElections.push_back(President("Franklin ", "USA", 1938));
President obama("obama ", "USA", 1966);
reElections.push_back(obama);
std::cout << "moved:\n" << obama.name
<< obama.country << obama.year <<std::endl;
std::cout << "\nContents:\n";
for (President const& president: elections) {
std::cout << president.name << " elected president of "
<< president.country << " in " << president.year << ".\n";
}
for (President const& president: reElections) {
std::cout << president.name << " re-elected president of "
<< president.country << " in " << president.year << ".\n";
}
}
结果输出
emplace_back:
I am being constructed.
I am being constructed.
I am being copy constructed.
I am being destructed.
I am being constructed.
I am being copy constructed.
I am being copy constructed.
I am being destructed.
I am being destructed.
push_back:
I am being constructed.
I am being moved.
I am being destructed.
I am being constructed.
I am being moved.
I am being copy constructed.
I am being destructed.
I am being destructed.
I am being constructed.
I am being moved.
I am being copy constructed.
I am being copy constructed.
I am being destructed.
I am being destructed.
I am being destructed.
Contents:
Nelson elected president of frica in 1994.
Nelson elected president of Africa in 1995.
Nelson elected president of Africa in 1996.
Franklin re-elected president of USA in 1936.
Franklin re-elected president of USA in 1937.
Franklin re-elected president of USA in 1938.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
I am being destructed.
vector空间自动增长测试代码
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
struct X{
X(int a) {x=a;cout << "调用构造函数:X()" << a << endl;}
X(const X& Xa) {x=Xa.x; cout << "调用拷贝构造函数:X(const X&)" << x << endl;}
~X(){cout << "调用析构函数:~X()" << x << endl;}
int x;
};
int main(int argc, char **argv)
{
cout << "定义局部变量:" << endl;
X x(1);
X y(2);
std::vector<X> vec;
cout << "\n存放在容器:" << endl;
vec.push_back(y);
vec.push_back(x);
vec.push_back(y);
cout << endl;
cout << "程序结束!!!" << endl;
return 0;
}
输出结果
定义局部变量:
调用构造函数:X()1
调用构造函数:X()2
存放在容器:
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用拷贝构造函数:X(const X&)2
调用析构函数:~X()2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)2
调用拷贝构造函数:X(const X&)1
调用析构函数:~X()2
调用析构函数:~X()1
程序结束!!!
调用析构函数:~X()2
调用析构函数:~X()1
调用析构函数:~X()2
调用析构函数:~X()2
调用析构函数:~X()1
上一篇: Matplotlib子图相关操作
推荐阅读