为什么仅当向量中已有元素时才调用移动构造函数?
Why is the move constructor only called when there is already an element in the vector?
我正在尝试学习 C++11 中的新功能。我正在 XCode.
中测试以下代码
#include <iostream>
#include <string>
#include <vector>
class CClass
{
std::string s;
public:
CClass()
{
std::cout<<"Default Constructor"<<std::endl;
}
CClass(const std::string v) :s(v) {
std::cout<<"Constructor"<<std::endl;
}
CClass(const CClass& other): s(other.s) {
std::cout<<"Copy Constructor"<<std::endl;
}
CClass(CClass&& a) noexcept
{
std::cout<<"Move Constructor"<<std::endl;
s = std::move(a.s);
}
CClass& operator = (const CClass& other)noexcept
{
std::cout<<"Copy Assignment"<<std::endl;
if(this != &other)
{
s = other.s;
}
return *this;
}
CClass& operator = (CClass&& other) noexcept
{
std::cout<<"Move Assignment"<<std::endl;
if(this != &other)
{
s = std::move(other.s);
}
return *this;
}
};
int main()
{
std::vector<CClass> v;
CClass x("hello");
//v.push_back(x);
std::cout<<"--------------------"<<std::endl;
v.emplace_back("uiuiu");
std::cout<<"--------------------"<<std::endl;
}
当我取消对推回的注释时,我得到以下结果:
Constructor
Copy Constructor
--------------------
Constructor
Move Constructor
--------------------
否则,如果我评论它,我得到:
Constructor
--------------------
Constructor
--------------------
我的问题是为什么在第二种情况下没有调用移动构造函数?它只在第一种情况下被调用,当 vector 最初不为空时。
这是因为向量中的一个元素需要移动到一个新的内存位置。发生这种情况的原因是新大小会超过向量容量,因此必须为向量分配具有新容量的新内存。
If the new size()
is greater than capacity()
then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.
迭代器和引用失效的原因相同:因为元素现在存储在内存中的新位置。
如果您在第一种情况下调用 reserve
,您将看到没有调用任何移动构造函数:
CClass x{"hello"}; // constructor
v.reserve(2); // make space for 2 elements (you could have also used resize)
v.push_back(x); // copy constructor
v.emplace_back("uiuiu"); // constructor
我正在尝试学习 C++11 中的新功能。我正在 XCode.
中测试以下代码#include <iostream>
#include <string>
#include <vector>
class CClass
{
std::string s;
public:
CClass()
{
std::cout<<"Default Constructor"<<std::endl;
}
CClass(const std::string v) :s(v) {
std::cout<<"Constructor"<<std::endl;
}
CClass(const CClass& other): s(other.s) {
std::cout<<"Copy Constructor"<<std::endl;
}
CClass(CClass&& a) noexcept
{
std::cout<<"Move Constructor"<<std::endl;
s = std::move(a.s);
}
CClass& operator = (const CClass& other)noexcept
{
std::cout<<"Copy Assignment"<<std::endl;
if(this != &other)
{
s = other.s;
}
return *this;
}
CClass& operator = (CClass&& other) noexcept
{
std::cout<<"Move Assignment"<<std::endl;
if(this != &other)
{
s = std::move(other.s);
}
return *this;
}
};
int main()
{
std::vector<CClass> v;
CClass x("hello");
//v.push_back(x);
std::cout<<"--------------------"<<std::endl;
v.emplace_back("uiuiu");
std::cout<<"--------------------"<<std::endl;
}
当我取消对推回的注释时,我得到以下结果:
Constructor
Copy Constructor
--------------------
Constructor
Move Constructor
--------------------
否则,如果我评论它,我得到:
Constructor
--------------------
Constructor
--------------------
我的问题是为什么在第二种情况下没有调用移动构造函数?它只在第一种情况下被调用,当 vector 最初不为空时。
这是因为向量中的一个元素需要移动到一个新的内存位置。发生这种情况的原因是新大小会超过向量容量,因此必须为向量分配具有新容量的新内存。
If the new
size()
is greater thancapacity()
then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.
迭代器和引用失效的原因相同:因为元素现在存储在内存中的新位置。
如果您在第一种情况下调用 reserve
,您将看到没有调用任何移动构造函数:
CClass x{"hello"}; // constructor
v.reserve(2); // make space for 2 elements (you could have also used resize)
v.push_back(x); // copy constructor
v.emplace_back("uiuiu"); // constructor