4

I've just been doing some exercises with move semantic, and I can't seem to figure out why my move assignment operator is not being called

My class is as follows (please ignore any bad practice that is not relevant to the question):

private:
    int sz;
    double* elems;

public:
    Vector(int size):sz(size), elems(new double[size])
    {
         for(int i=0; i!=sz; ++i)
         {
             elems[i] = i;
         }
    }

    ~Vector()
    {
         std::cout << "Destruct " << std::endl; delete [] elems;
    }

    double& operator[](int i)
    {
        return elems[i];
    }
    const double& operator[](int i)const 
    {
         return elems[i];
    }

    //operator+ to add vectors
    friend Vector operator+(const Vector& a, const Vector& b)
    {

        Vector ret(a.sz);
        if(a.sz!=b.sz)
            return 0;
        std::cout << "Adding" << std::endl;
        for(int i=0; i!=a.sz; ++i)
        {
            ret[i] = a[i] + b[i];
        }

        return ret;
     }

     //move constructor
     Vector(Vector&& a): sz(a.sz),elems(a.elems)
     {
          std::cout << "Move constructor"<< std::endl;
          a.elems = nullptr;
          a.sz = 0;
     }

     //move assignment
     Vector& operator=(Vector&& a)
     {
        std::cout << "Moveeee" << std::endl;
        delete [] elems;
        elems = a.elems;
        sz = a.sz;
        a.elems = nullptr;
        a.sz = 0;

        return *this;
     }

Now my test case is as follows:

Vector v1(3);
Vector v2(3);
Vector v3(3);
Vector v4 = v1+v2;

The output is as follows:

Adding
Move constructor
Destruct
Destruct
Destruct
Destruct
Destruct

What I expect is line Vector v4 = v1+v2; to call the move assignment, but it doesn't. Instead it calls the move constructor.

I even tried Vector v4 = std::move(v2);, but that also didn't work and called the move constructor.

Any idea why the move assignment is not being called?

6
  • 1
    It's basically an optimization by the compiler. The assignment operator will only be called after the object has been constructed. If you do Vector v4; v4 = v1 + v2;, the assignment operator should be called. Commented Feb 19, 2014 at 1:37
  • 2
    Before you move on to C++11, you should first understand what assignment is -- your code doesn't have any! Instead, you have copy-initialization. Commented Feb 19, 2014 at 1:39
  • 1
    @leetNightshade: It's not an optimization. It's an entirely different construct altogether. Commented Feb 19, 2014 at 1:40
  • @Kerrek SB Do you know what the construct is called? Commented Feb 19, 2014 at 1:42
  • 1
    @leetNightshade: Yes, it's called "copy-initialization". Commented Feb 19, 2014 at 1:42

1 Answer 1

9

Semantically you are not calling assignment

Vector v4 = v1+v2;

is really:

Vector v4(v1+v2);

If there is no copy constructor, but a default constructor and an acceptable assignment exists, then assignment will be called. As commented you would need to do:

Vector v4; v4 = v1 + v2;

to have a true assignment

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.