What are move semantics and copy semantics in C++11?
Overview
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.
Copy semantics
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
Example
#include "IntegerList.h"#include<vector>int main(){std::vector<IntegerList> v;v.push_back(IntegerList(25));return 0;}
Explanation
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
IntegerListclass to allocate the memory. -
Lines 14–21: We define the copy constructor for the
IntegerListclass. Theconst IntegerList & objshows 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
IntegerListclass to deallocate the memory. -
Lines 33–35: We declare the attributes for the
IntegerListclass.
In the main.cpp file:
-
Line 6: We declare a
vector Vector is a contiguous memory container that can change its size during runtime. vofIntegerListtype. -
Line 7: We push a nameless
IntegerListobject 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.
Move semantics
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
Example
#include "IntegerList.h"#include<vector>int main(){std::vector<IntegerList> v;v.push_back(IntegerList(25));return 0;}
Explanation
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
IntegerListclass to allocate the memory. -
Lines 14–21: We define the copy constructor for the
IntegerListclass. Theconst IntegerList & objshows 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
IntegerListclass. TheIntegerList && objshows 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
IntegerListclass to deallocate the memory. -
Lines 40–42: We declare the attributes for the
IntegerListclass.
In main.cpp file:
-
Line 6: We declare a
vector Vector is a contiguous memory container that can change its size during runtime. vofIntegerListtype. -
Line 7: We push an
IntegerListobject 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