In this article we will discuss the use of rvalue references in C++11 move semantics.

Problem of Temporary Objects

The Idea behind this move semantics is to reduce the load of these temporary objects on memory. Every time we return a object from a function then a temporary object is created, which eventually get copied. In then end we create 2 copies of an object whereas, we need only one. Let’s understand by an example,

Suppose we have a Container class that contains a integer pointer as member variable,

When we create an object of Container class, then its default constructor internally allocates an array of 20 int on heap and assign it to its member variable.

Similarly, Container class’s copy constructor allocates an array of 20 int on heap, then copy the contents of passed objects array into it and then assign it to its member variable.

Generally, we use Factory classes to create object of our classes. On similar lines, let’s create a simple function that creates an object of Class Container and returns i.e.

Now in main function we created a vector of Container type and inserted an object returned by getContainer() function i.e.

Now, at last there is one object in the vector  vecOfContainers. But we actually created 2 objects for it because getContainer() function returned a temporary object which got copied into a new object and then destructed. This 2nd object got inserted in vector. So, 2 objects of class Container are created at following step in above code,

  • One inside the getContainer() function using Container class’s default constructor
  • Second while adding object in vector using Container class’ copy constructor.

To create each of these 2 objects it allocated an array of 20 int on heap 2 times and at last only one was used. So, its clearly a wastage of resources and effort.

How to solve this problem of resource and effort wastage due to temporary objects? Is there a way to move the 1st object instead of creating 2nd one and copying contents to it?

Answer is yes. This is where move semantics and rvalue references comes into picture.

Solving Problem of Temporary Objects using rvalue references & Move Constructor

The getContainer() function here is a rvalue, so it can be referred by a rvalue reference. Also, using rvalue reference we can also overload functions. This time, we will overload the Constructor of class Container and this new Constructor will be called move constructor.

Move Constructor

Move constructor takes a rvalue reference as an argument and that makes it overloaded because Copy Constructor takes the const lvalue reference as an argument. In Move constructor we just move the member variables of passed object into the new object’s member variables, instead of allocating new memory for them.

Let’s see the move constructor for class Container i.e.

In the move constructor, we just copied the pointer. Now member variable m_Data points to the same memory on heap. Then we set the m_Data of passed object to NULL. So, we didn’t allocated any memory on heap in move constructor, we just shifted the control of memory.

Now if we create the vector  of class container and push a object returned from getContainer() into it. Then a new object will created from this temporary object but as getContainer() is a rvalue, so Move Constructor of this new Container class’s object will be called and in that memory will be just shifted. So, actually on heap we will create only one array of integers.

 

Similar to Move Constructor we can have Move Assignment operator that will just shift the content. Checkout the complete example as follows,

Output:

In the above example, Move constructor of class Container will be called because getContainer() returns a rvalue and Container class has a overloaded version of Constructor that accepts rvalue in rvalue reference. Inside this Move constructor memory is just shifted.

Similarly in following lines,

Move Assignment Operator was called instead of assignment operator and memory just got shifted.

Click Here to Subscribe for more Articles / Tutorials like this.