我正在学习C++ 11中的移动语义.我写了一个小程序来测试移动语义的行为.但它没有像我预期的那样表现,有人能解释我为什么吗?
#include<iostream>
using namespace std;
class Vector
{
public:
Vector()
{
cout << "empty Ctor"<<endl;
array = new int[10];
size = 10;
}
Vector(int n)
{
array = new int[n];
size = n;
for (int i=0; i<size; ++i)
array[i] = i;
cout << "Ctor"<<endl;
}
Vector(const Vector& v):size(v.size)
{
array = new int[size];
for (int i=0; i<size; ++i)
array[i] = v.array[i];
cout << "copy"<<endl;
}
Vector(Vector&& v):size(v.size)
{
array = v.array;
v.array = nullptr;
cout << "move"<<endl;
}
~Vector()
{
delete array;
}
private:
int* array;
int size;
};
int main() {
Vector v(10); //print Ctor. (as expected)
Vector v1(std::move(v)); //print move. (as expected)
Vector v2(*(new Vector(2))); //print Ctor, copy. (I expect Ctor, move)
Vector v3(Vector(2)); //print only Ctor. (I expect Ctor, move)
}
Run Code Online (Sandbox Code Playgroud)
那么,为什么印刷品不符合我的预期.因为我认为传递给v2和v3的值都是Rvalue.而对于v3,为什么它只打印Ctor而不打印"移动"或"复制"
Tar*_*ama 11
Vector v2(*(new Vector(2)));
Run Code Online (Sandbox Code Playgroud)
new Vector(2) 是一个右值,但取消引用它会产生左值,因此副本而不是移动.
Vector v3(Vector(2));
Run Code Online (Sandbox Code Playgroud)
由于临时Vector是不必要的,因此编译器将省略该副本.您的编译器可能有一个标志来禁用复制省略,以便您可以看到额外的移动,例如-fno-elide-constructors在GCC和Clang中.