C++

C++ : Move Assignment Operator

Move assignment operator
- Move assignment : The move assignment could be suggested using std :: move ( T&& obj ). This enforces move semantics to transfer the resources from one object to another object .
 obj = std :: move ( tmp_obj ); 
The std :: move ( T&& obj ) converts the lvalue of obj into an xvalue. ( xvalue represents an object whose resources could be reused.)
Note : After the std :: move ( tmp_obj ) call, the tmp_obj loses its value.
- Parameter : The move assignment operator for a class takes an rvalue reference ( && ) to the class type as its parameter.
String& operator = (String&& obj) {
. . .
}
- Check before assigning : To prevent an object getting assigned to itself, a conditional block is used
if ( this != &obj ) { 
  // Do the assignment
}

C++ program for a String class demonstrates the move assignment operator.

#include <iostream>
#include <vector>
#include <string>

int main () {

    std :: string noddy = "noddy";
    std :: string deltoid = "deltoid";
    std :: vector < std :: string> str_vec;

    std :: cout << "\nBefore push " << std :: endl;
    std :: cout << "noddy : [" << noddy << "]" << std :: endl;
    std :: cout << "deltoid : [" << deltoid << "]" << std :: endl;
    std :: cout << "\nContent of vector : " << noddy << std :: endl;

    str_vec.push_back (noddy); // A copy operation
    str_vec.push_back (std :: move (deltoid)); // A move operation

    for (const auto& str : str_vec ) {
         std :: cout << str << std :: endl;
    }

    std :: cout << "\nAfter push " << std :: endl;
    std :: cout << "noddy : [" << noddy << "]" << std :: endl;
    std :: cout << "deltoid : [" << deltoid << "]" << std :: endl;

    return 0;
}

Output

Before push 
noddy : [noddy]
deltoid : [deltoid]

Content of vector : noddy
noddy
deltoid

After push 
noddy : [noddy]
deltoid : []

#include<iostream>
#include<cstring>

class String {

    private:
    u_int m_len;
    char* m_buff;

    public:
    // Default constructor
    String () {
        std :: cout << "Default constructor of String class got called." << std :: endl;
        m_len = 0;
        m_buff = new char;
        m_buff[0] = '\0';
    }

    // Parameterized constructor
    String (const char * str) {
        std :: cout << "Parameterized constructor of String class got called." << std :: endl;
        m_len = strlen(str);
        m_buff = new char[m_len + 1];
        strcpy(m_buff, str);
    }

    String (String&& obj) {
        m_len = obj.m_len;
        m_buff = obj.m_buff;

        obj.m_len = 0;
        obj.m_buff = nullptr;
    }

    // Overloading = operator for String class
    String& operator = (const String& obj) {
        std :: cout << "Overloaded assignment operator for String class got called." << std :: endl;
        if (this == &obj) { // If the source obj is same as the destn object, no need to copy.
            return (*this);
        } else {
            m_len = obj.m_len;
            delete [] m_buff; // Delete the old buffer of the destination object.
            m_buff = new char[m_len+1];
            strcpy(m_buff, obj.m_buff);
            return (*this);
        }
    }

    // Move assignment operator for String class
    String& operator = (String&& obj) {
        std :: cout << "Move assignment operator for String class got called." << std :: endl;
        if (this != &obj) { // If the source obj is same as the destn object, no need to move.
            m_len = obj.m_len;
            m_buff = obj.m_buff;

            obj.m_len = 0;
            obj.m_buff = nullptr;
        }
        return (*this);
    }

    ~String() {
        std :: cout << "Destructor String class got called." << std :: endl;
        if (m_buff) {
            std :: cout << "Deleting the buffer." << std :: endl;
           delete [] m_buff;
        }
    }

    void Display() {
        std :: cout << m_buff << std :: endl;
    }
};

int main() {

   String deltoid("Deltoid");
   String deltoid_right;

   deltoid_right = std :: move(deltoid); // Call the move assignment operator.
   // deltoid_right = deltoid; // Call the overloaded assignment operator.

   std :: cout << "Main ends. Now returning." << std :: endl;
   return 0;
}

Output

Parameterized constructor of String class got called.
Default constructor of String class got called.
Move assignment operator for String class got called.
Main ends. Now returning.
Destructor String class got called.
Deleting the buffer.
Destructor String class got called.


Copyright (c) 2019-2021, Algotree.org.
All rights reserved.