Move operation
Operation that is being used to move (steal) the value from source object to destination object and leaving source object in valid state and unspecified state.
Move Semantics
These are two operations (Move constructor and Move assignment) that are used to move the value of object instead of copy. These will be provided by compiler by default like copy constructor, assign operator, default constructor and destructor, if we don’t define by our-self.
Move Constructor
It is constructor that mean we are creating new object and getting(stealing) value from object and leaving that object in valid state and unspecified state. It will be provided by compiler by default, we can define it like below and it will NOT be overwritten by compiler.
mystring:: mystring(mystring&& tmp) { std::cout<<"move constructor"<<std::endl; mpStr = tmp.mpStr; tmp.mpStr = nullptr; }
Example:
std::string s11{"digestcpp.com"}; // If we creates new object then we need constructor. // If we want to move the object instead of copy then // We need Move constructor std::string s22{std::move(s11)}; std::cout<<"s22:"<<s22<<std::endl; std::cout<<"s11:"<<s11<<std::endl; Output: s22:digestcpp.com //got the new value that stolen from s11 object s11: //s11 has nullptr and its in valid and specified state
Move Assignment Operator
It is operator to assign the new value to existing object and getting (stealing) new value from object and leaving that object in valid state and unspecified state. It will be provided by compiler by default, we can define it like below and it will NOT be overwritten by compiler.
mystring& mystring::operator=(mystring&& tmp) { std::cout<<"move assignment operator"<<std::endl; if(this != &tmp) { if(mpStr) delete[] mpStr; mpStr = tmp.mpStr; tmp.mpStr = nullptr; } return *this; }
Example:
std::string s11{"digestcpp.com"}; std::string s22; // If we assign the value that mean object already exist. // If we want to move the object instead of copy then // We need move assign operator s22 = {std::move(s11)}; std::cout<<"s22:"<<s22<<std::endl; std::cout<<"s11:"<<s11<<std::endl; Output: s22:digestcpp.com //got the new value that stolen from s11 object s11: //s11 has nullptr and its in valid and specified state
Source code with example using default move semantics:
/* Program:Move Semantics Author: Alpha Master Date: 4 March 2021 */ //Header File #include<iostream> int main() { //string with default function that are provided by compiler std::cout<<"Move Semantics means operation that steal value or resource from other object"<<std::endl; std::string s1{"digestcpp.com"};//param constructor std::cout<<"s1 with param constructor, s1:"<<s1<<std::endl; std::string s2{s1}; //copy constructor std::cout<<"s2 with copy constructor, s2:"<<s2<<std::endl; std::string s3; //default constructor s3 = s1; //assignment operator std::cout<<"s3 with assignment operator, s3"<<s3<<std::endl; std::string s4{std::move(s3)}; //move constructor std::cout<<"s4 with move constructor, stole from s3, s4:"<<s4<<std::endl; std::cout<<"Check s3 that we moved, s3:"<<s3<<"Its empty"<<std::endl; std::string s5; //default constructor s5=std::move(s4); //move assignment operator std::cout<<"s5 with move assignment, stole from s4, s5:"<<s5<<std::endl; std::cout<<"Check s4 that we moved, s4:"<<s4<<"Its empty"<<std::endl; return 0; }
Output:
Move Semantics means operation that steal value or resource from other object s1 with param constructor, s1:digestcpp.com s2 with copy constructor, s2:digestcpp.com s3 with assignment operator, s3digestcpp.com s4 with move constructor, stole from s3, s4:digestcpp.com Check s3 that we moved, s3:Its empty s5 with move assignment, stole from s4, s5:digestcpp.com Check s4 that we moved, s4:Its empty
Source code with example using user defined move semantics:
/* Program:Move Semantics Author: Alpha Master Date: 4 March 2021 */ //Header File #include<iostream> #include<string.h> //My String with all default functionlities class mystring { char* mpStr; public: mystring(char* tmp = nullptr); //default & parameterized constructor ~mystring(); //destructor mystring(const mystring&); //copy constructor mystring& operator=(const mystring&); //assignment operator mystring(mystring&&); //move contructor mystring& operator=(mystring&&); //move assigment operator //Function to print friend std::ostream &operator<<(std::ostream &output, const mystring& tmp ) { if(tmp.mpStr != nullptr) { output <<"mystring :" << tmp.mpStr << std::endl; } else { output <<"mystring : Its empty" << std::endl; } return output; } }; mystring::mystring(char* tmp) { std::cout<<"default & parameterized constructor"<<std::endl; if(tmp != nullptr) { mpStr = new char[strlen(tmp) + 1]; strcpy(mpStr, tmp); } } mystring::~mystring() { //std::cout<<"destructor"<<std::endl; if(mpStr) { delete[] mpStr; } } mystring::mystring(const mystring& tmp) { std::cout<<"copy constructor"<<std::endl; mpStr = new char [strlen(tmp.mpStr) + 1]; strcpy(mpStr, tmp.mpStr); } mystring& mystring::operator=(const mystring& tmp) { std::cout<<"assignment operator"<<std::endl; if(this != &tmp) { if(mpStr) delete[] mpStr; mpStr = new char [strlen(tmp.mpStr) + 1]; strcpy(mpStr, tmp.mpStr); } return *this; } mystring:: mystring(mystring&& tmp) { std::cout<<"move constructor"<<std::endl; mpStr = tmp.mpStr; tmp.mpStr = nullptr; } mystring& mystring::operator=(mystring&& tmp) { std::cout<<"move assignment operator"<<std::endl; if(this != &tmp) { if(mpStr) delete[] mpStr; mpStr = tmp.mpStr; tmp.mpStr = nullptr; } return *this; } int main() { std::cout<<"Move Semantics"<<std::endl; mystring s11("digestcpp.com");//param constructor std::cout<<s11; mystring s12(s11); //copy constructor std::cout<<s12; mystring s13; //default constructor s13 = s11; //assignment operator std::cout<<s13; mystring s14(std::move(s13)); //move constructor std::cout<<s14; std::cout<<"We have moved s13 by move contructor so expecting empty"<<std::endl; std::cout<<s13; mystring s15; //default constructor s15 = std::move(s14); //move assignment operator std::cout<<s15; std::cout<<"We have moved s14 by move assignment so expecting empty"<<std::endl; std::cout<<s14; std::cout<<std::endl; return 0; }
Output:
Move Semantics default & parameterized constructor mystring :digestcpp.com copy constructor mystring :digestcpp.com default & parameterized constructor assignment operator mystring :digestcpp.com move constructor mystring :digestcpp.com We have moved s13 by move contructor so expecting empty mystring : Its empty default & parameterized constructor move assignment operator mystring :digestcpp.com We have moved s14 by move assignment so expecting empty mystring : Its empty