Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understand the move constructor behavior in this example

Tags:

c++

c++11

I am learning the move semantics in C++11. I wrote a small program to test the behavior of move semantics. But it does not behave as what I expected, could someone explain me why?

#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)

}

So, why the print is not what I expected. Since I think both value passed to v2 and v3 are Rvalue. And for v3, why it print only Ctor without printing "move" or "copy"

like image 793
xeonqq Avatar asked Dec 20 '22 00:12

xeonqq


1 Answers

Vector v2(*(new Vector(2)));

new Vector(2) is an rvalue, but dereferencing it produces an lvalue, hence the copy rather than the move.

Vector v3(Vector(2));

Since the temporary Vector is unnecessary, the copy will be elided by the compiler. Your compiler may have a flag to disable copy elision so that you can see the additional move, e.g. -fno-elide-constructors in GCC and Clang.

like image 196
TartanLlama Avatar answered Jan 06 '23 16:01

TartanLlama