Since, C++11, apart from existing compiler generated functions (i.e., constructor, destructor, assignment operator & copy constructor) 2 more special functions are generated by compiler, a move constructor and a move assignment operator.
class MainFunda
{
public:
MainFunda(MainFunda&& rhs); // move constructor
MainFunda& operator=(MainFunda&& rhs);
// move assignment operator
};
Although, the signatures of these functions look very similar to traditional copy constructor and assignment operator, except they take R-value arguments. Therefore, such functions are called when construction or assignment of an object happens with temporaries.
The important rule is that the compiler generates these move functions only when the class needs them. Please also refer rule of three below. The compiler automatically generates move member operations only when following three conditions become true:
- When class has no copy constructors
- Secondly, when class do not have any move operations
- And last when there is no destructor
The move constructor
constructs an object on the basis of C++ move operations directly from R-value. Such a constructor constructs each non-static data member of the class from the corresponding member of its parameter rhs.
Move Operations in Inheritance :
The move constructor of derived class also (move) constructs its base class part (if there are any). However, there is no guarantee that compiler will call a move constructor in base class part of initialization. This is because, if there is no valid move constructor present, then compiler calls copy constructor code to initialize base class.
Example: This following code shows that there is a user-defined constructor (move) in the Base class. And there is a compiler-generated move constructor in Derived class. Finally, compiler generated move-constructor in Derived class calls user-defined move constructor.
#include <iostream> //main header
using namespace std;//for namespace
class MFBase
{
public:
MFBase()
{
cout << "Base Constructor" << endl;
}
MFBase(const MFBase& rhs) //copy constructor
{
cout << "Base Copy Constructor" << endl;
}
MFBase(MFBase&& rhs) //move constructor
{
cout << "Base Move Constructor" << endl;
}
};
class MFDerived : public MFBase
{ //compiler-generated move constructor
};
int main()
{
MFDerived d1;
MFDerived d2 = std::move(d1); //Calls move constructor
return 0;
}
The output is:
Base Constructor
Base Move Constructor