Move semantics are used to move resources from one object to another without copying. This is applicable when we try to pass an object to a function or when an object is being returned from a function.
In the previous versions of C++, we used return by pointer and return by reference to move the data of one object to another. But with the release of C++11, the concept of move semantics was introduced. That allows saving costs on copying the data from one object to another.
Before C++11, the instantiation of unnecessary temporary objects was a problem. It usually slows downs the program and acquires extra space in memory. The instantiation of temporary objects usually occurs when we pass an object to a function by value or return an object through a function by value. It uses copy semantics which copies the actual data of the existing object and assigns it to the new temporary object. Copy semantics uses copy constructor and
#include "IntegerList.h"#include<vector>int main(){std::vector<IntegerList> v;v.push_back(IntegerList(25));return 0;}
In IntegerList.h
file:
Line 4: We create a class named IntegerList
.
Lines 9–12: We define the parameterized constructor with default arguments for the IntegerList
class to allocate the memory.
Lines 14–21: We define the copy constructor for the IntegerList
class.
The const IntegerList & obj
shows the const l-value reference used in copy constructors. The operator &
can be used on l-values.
Lines 23–31: We define the destructor for the IntegerList
class to deallocate the memory.
Lines 33–35: We declare the attributes for the IntegerList
class.
In the main.cpp
file:
Line 6: We declare a v
of IntegerList
type.
Line 7: We push a nameless IntegerList
object into the vector.
We can see in the output tab that the parameterized constructor is called for the nameless object being made, and while pushing it into the vector, a copy of that object is made through the copy constructor using copy semantics — before the temporary nameless object gets destroyed.
Note: This is the unnecessary temporary copy of the object that copy semantics create while pushing it into the vector.
We can get rid of this temporary copy to avoid the extra cost using move semantics being introduced in C++11.
In C++11, the resources of the objects can be moved from one object to another rather than copying the whole data of the object to another. This can be done by using move semantics in C++11. Move semantics points the other object to the already existing object in the memory. It allows avoiding the instantiation of unnecessary temporary copies of the objects by giving the resources of the already existing object to the new one and safely taking from the existing one. Taking resources from the old existing object is necessary to prevent more than one object from having the same resources. Move semantics uses move constructor and
#include "IntegerList.h"#include<vector>int main(){std::vector<IntegerList> v;v.push_back(IntegerList(25));return 0;}
In IntegerList.h
file:
Line 4: We create a class named IntegerList
.
Lines 9–12: We define the parameterized constructor with default arguments for the IntegerList
class to allocate the memory.
Lines 14–21: We define the copy constructor for the IntegerList
class.
The const IntegerList & obj
shows the const l-value reference which is used in copy constructors. The operator &
can be used on l-values.
Lines 23–28: We define the move constructor for the IntegerList
class.
The IntegerList && obj
shows the non-const r-value reference used in move constructors. The operator &&
can be used on r-values.
Line 23: We also give the resources of the old object to the new one.
Line 26: We take resources from the old object to prevent more than one object from having the same resource.
Lines 30–38: We define the destructor for the IntegerList
class to deallocate the memory.
Lines 40–42: We declare the attributes for the IntegerList
class.
In main.cpp
file:
Line 6: We declare a v
of IntegerList
type.
Line 7: We push an IntegerList
object into the vector.
We can see in the output tab that the parameterized constructor is called for the nameless object being made, and while pushing it into the vector no temporary copy of the object is made. Instead of creating a temporary copy and calling the copy constructor, it uses move semantics and moves the data of the object by calling the move constructor. So by using move semantics the unnecessary instantiation of temporary copies is avoided and code is made less expensive.
Note: We can also make the move assignment operator to use move semantics during assignment.
Free Resources