了解此示例中的移动构造函数行为

xeo*_*nqq 4 c++ c++11

我正在学习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中.