前面回答的比较乱,后来我又想了一下以及试验了一下:
个人理解是这样的,分为两种情况讨论。
(1)如果我们是先构造一个类对象,之后再进行push_back(),那么应该是调用一次拷贝构造函数
(2)如果我们是在push_back()的同时,在push_back中构造一个对象,那么实际上是调用一次构造函数,之后调用一次移动构造函数(C++11中的右值以及移动构造函数)
而由于右值引用的概念,因此,C++11中有emplace_back来实现和push_back相同的功能,但是此时,和上面(2)相同的情况下,仅仅有一次构造函数调用,之后Move直接移交所有权(因此emplace_back的优势也在这里,少了一次调用)
可以看下面的代码试一下:
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
President(const President& other) //拷贝构造函数
: name(std::move(other.name)), country(std::move(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);
};
int main()
{
std::vector<President> elections;
std::cout << "emplace_back:\n";
elections.emplace_back("Nelson Mandela", "South Africa", 1994);
//只有一次构造
std::vector<President> reElections;
std::cout << "\npush_back:\n";
reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
//上面是提到的(2)的情形,调用构造+移动
std::vector<President> reElections;
President pb=President("Franklin Delano Roosevelt", "the USA", 1936);
reElections.push_back(pb);
//上面是(1)的情形,调用拷贝构造函数
}