这个问题看起来很奇怪,但我已经检查了多个编译器。在我的代码中,我有一个Move Constructor
和一个copy constructor
class A {
int val;
public:
A(int var) : val(var) {
}
A( A && a1) {
cout<<"M Value -> "<<a1.val<<endl;
cout<<"Move Cons..."<<endl;
}
A(const A & a1) {
cout<<"Copy Cons.."<<endl;
cout<<"Value -> "<<a1.val<<endl;
}
};
如果我把我的main
函数写成
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(move(a2));
}
输出是
M Value -> 200
Move Cons...
这是预期的,但如果我改变我的main
功能
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(A(100));
v1.push_back(move(a2));
}
我得到以下输出
M Value -> 100
Move Cons...
M Value -> 200
Move Cons...
Copy Cons.. // unexpected
Value -> 0 // unexpected
任何人都可以帮助我了解这个copy constructor
被调用的地点和方式..这也是值0
谢谢
原因已在评论中得到解答。我会试着说明发生了什么。
vector<A> v1;
v1.push_back(A(100));
A(100)
在向量内的移动。v1.push_back(move(a2));
std::vector
将其内容保存在连续的内存中。a2
移到v1
内。v1
的其余元素(在本例中仅为第一个)复制到新的v1
。1) ## v1[undef ] #########################
2) ## v1[A(100)] #########################
3) ## [A(100)] ### v1[undef, undef ] ##
4) ## [A(100)] ### v1[undef, A(200)] ##
5) ## [A(100)] ### v1[A(100), A(200)] ##
与值0相关,这是因为这些复制和移动构造函数实际上什么也不做,并且val
值仍未定义。使用适当的构造函数,此日志应为100。
如果将移动构造函数标记为noexcept
,则将在重新分配过程中使用它而不是复制过程。
您可以使用v1.emplace_back(100)
而不是v1.push_back(A(100))
避免移动。