C++ Tutorial

Class and Object

Reference

Inheritance and Derivation

Polymorphism and Virtual Functions

Operator Overloading

Template

Exception

Object Oriented Advanced

Input/Output Stream

File Operations

Overloads = (Assignment Operator) in C++

In this tutorial, we will learn how to overload the assignment operator = for a custom class in C++. Overloading the assignment operator allows you to properly assign one object to another object of the same class while taking care of issues like deep copying, resource management, and self-assignment.

Let's demonstrate overloading the assignment operator using a simple Vector2D class as an example.

  • Create a simple Vector2D class:

First, let's create a basic Vector2D class with a constructor and a function to display the vector:

#include <iostream>

class Vector2D {
    int x;
    int y;

public:
    // Constructor
    Vector2D(int x, int y) : x(x), y(y) {}

    // Function to display the vector
    void display() const {
        std::cout << "(" << x << ", " << y << ")";
    }
};
  • Overload assignment operator (=):

To overload the assignment operator for the Vector2D class, define a member function with the following syntax:

Vector2D& operator=(const Vector2D& rhs) {
    // implementation
}

In the implementation, you should:

  • Check for self-assignment: If the object being assigned is the same as the object being assigned to, do nothing and return a reference to the current object.
  • Perform deep copy: Make sure to copy all data members from the right-hand side object (rhs) to the left-hand side object (i.e., *this).
  • Return a reference to the current object.

Here's the complete implementation for overloading the assignment operator in the Vector2D class:

// Overloading the assignment operator
Vector2D& operator=(const Vector2D& rhs) {
    // Check for self-assignment
    if (this == &rhs) {
        return *this;
    }

    // Deep copy
    x = rhs.x;
    y = rhs.y;

    // Return a reference to the current object
    return *this;
}

Add the above code inside the Vector2D class to overload the assignment operator.

  • Use the overloaded assignment operator:

Now you can use the overloaded assignment operator to assign one Vector2D object to another:

int main() {
    Vector2D vec1(3, 4);
    Vector2D vec2(1, 2);

    vec1.display(); // Output: (3, 4)
    vec2.display(); // Output: (1, 2)

    vec1 = vec2; // Assign vec2 to vec1 using the overloaded assignment operator

    vec1.display(); // Output: (1, 2)
    vec2.display(); // Output: (1, 2)

    return 0;
}

In this example, we create two Vector2D objects vec1 and vec2. We then assign vec2 to vec1 using the overloaded assignment operator, which properly handles the assignment.

That's it for our tutorial on overloading the assignment operator in C++. By overloading the assignment operator, you can ensure that your custom class objects are assigned correctly, taking care of issues like deep copying, resource management, and self-assignment.

  1. How to overload the = operator in C++:

    Overloading the = operator in C++ allows you to define custom behavior for assignment operations. Example:

    #include <iostream>
    
    class MyClass {
    private:
        int data;
    
    public:
        MyClass(int value) : data(value) {}
    
        // Overloading the = operator
        MyClass& operator=(const MyClass& other) {
            if (this != &other) {
                // Perform custom assignment
                data = other.data;
            }
            return *this;
        }
    
        void displayData() const {
            std::cout << "Data: " << data << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(42);
        MyClass obj2(99);
    
        // Using the overloaded = operator
        obj1 = obj2;
    
        obj1.displayData(); // Data: 99
    
        return 0;
    }
    
  2. Using assignment operator overloading for custom type assignments in C++:

    Assignment operator overloading allows for custom handling of assignments between objects of the same type. Example:

    #include <iostream>
    
    class Point {
    private:
        int x;
        int y;
    
    public:
        Point(int xVal, int yVal) : x(xVal), y(yVal) {}
    
        // Overloading the = operator for custom type assignment
        Point& operator=(const Point& other) {
            if (this != &other) {
                // Custom assignment
                x = other.x;
                y = other.y;
            }
            return *this;
        }
    
        void display() const {
            std::cout << "(" << x << ", " << y << ")" << std::endl;
        }
    };
    
    int main() {
        Point p1(1, 2);
        Point p2(3, 4);
    
        // Using the overloaded = operator for custom type assignment
        p1 = p2;
    
        p1.display(); // (3, 4)
    
        return 0;
    }
    
  3. Copy assignment operator overloading in C++:

    The copy assignment operator (=) is overloaded to define how an object should be assigned the values of another object of the same type. Example:

    #include <iostream>
    
    class MyClass {
    private:
        int data;
    
    public:
        MyClass(int value) : data(value) {}
    
        // Copy assignment operator overloading
        MyClass& operator=(const MyClass& other) {
            if (this != &other) {
                // Copy assignment
                data = other.data;
            }
            return *this;
        }
    
        void displayData() const {
            std::cout << "Data: " << data << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(42);
        MyClass obj2(99);
    
        // Copy assignment using the overloaded = operator
        obj1 = obj2;
    
        obj1.displayData(); // Data: 99
    
        return 0;
    }
    
  4. Deep copy and shallow copy with assignment operator overloading in C++:

    Deep copy and shallow copy behaviors depend on how the assignment operator is implemented. Example demonstrating deep copy:

    #include <iostream>
    #include <cstring>
    
    class String {
    private:
        char* str;
    
    public:
        // Constructor
        String(const char* s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
    
        // Copy constructor for deep copy
        String(const String& other) {
            str = new char[strlen(other.str) + 1];
            strcpy(str, other.str);
        }
    
        // Assignment operator for deep copy
        String& operator=(const String& other) {
            if (this != &other) {
                delete[] str; // Release existing memory
                str = new char[strlen(other.str) + 1];
                strcpy(str, other.str);
            }
            return *this;
        }
    
        // Display the string
        void display() const {
            std::cout << str << std::endl;
        }
    
        // Destructor
        ~String() {
            delete[] str;
        }
    };
    
    int main() {
        String s1("Hello");
        String s2("World");
    
        // Deep copy using the overloaded = operator
        s1 = s2;
    
        s1.display(); // World
    
        return 0;
    }
    

    For shallow copy, the assignment operator would simply copy the address, not the actual content.

  5. Self-assignment and overloading = operator in C++:

    To handle self-assignment, the assignment operator should check whether the source and destination objects are the same. Example:

    #include <iostream>
    
    class MyClass {
    private:
        int data;
    
    public:
        MyClass(int value) : data(value) {}
    
        // Overloading the = operator with self-assignment check
        MyClass& operator=(const MyClass& other) {
            if (this != &other) {
                // Perform assignment
                data = other.data;
            }
            return *this;
        }
    
        void displayData() const {
            std::cout << "Data: " << data << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(42);
    
        // Self-assignment using the overloaded = operator
        obj1 = obj1;
    
        obj1.displayData(); // Data: 42
    
        return 0;
    }
    
  6. C++ assignment operator overloading for user-defined types:

    Overloading the assignment operator for user-defined types allows custom assignment behavior. Example:

    #include <iostream>
    
    class ComplexNumber {
    private:
        double real;
        double imag;
    
    public:
        ComplexNumber(double r, double i) : real(r), imag(i) {}
    
        // Assignment operator overloading
        ComplexNumber& operator=(const ComplexNumber& other) {
            if (this != &other) {
                // Perform custom assignment
                real = other.real;
                imag = other.imag;
            }
            return *this;
        }
    
        void display() const {
            std::cout << real << " + " << imag << "i" << std::endl;
        }
    };
    
    int main() {
        ComplexNumber num1(1.0, 2.0);
        ComplexNumber num2(3.0, 4.0);
    
        // Using the overloaded = operator
        num1 = num2;
    
        num1.display(); // 3 + 4i
    
        return 0;
    }
    
  7. Chaining assignment operators in C++:

    Chaining assignment operators in C++ allows concise assignments of multiple values. Example:

    #include <iostream>
    
    class MyClass {
    private:
        int data;
    
    public:
        MyClass(int value) : data(value) {}
    
        // Chaining assignment operators
        MyClass& operator=(const MyClass& other) {
            if (this != &other) {
                // Perform assignment
                data = other.data;
            }
            return *this;
        }
    
        // Chaining assignment operators
        MyClass& operator+=(const MyClass& other) {
            // Perform addition and assignment
            data += other.data;
            return *this;
        }
    
        void displayData() const {
            std::cout << "Data: " << data << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(42);
        MyClass obj2(99);
    
        // Chaining assignment operators
        obj1 = obj2 += MyClass(10);
    
        obj1.displayData(); // Data: 109
    
        return 0;
    }
    
  8. Combining = operator overloading with other operators in C++:

    Overloading = can be combined with other operators for comprehensive custom behavior. Example:

    #include <iostream>
    
    class ComplexNumber {
    private:
        double real;
        double imag;
    
    public:
        ComplexNumber(double r, double i) : real(r), imag(i) {}
    
        // Overloading = and += operators
        ComplexNumber& operator=(const ComplexNumber& other) {
            if (this != &other) {
                real = other.real;
                imag = other.imag;
            }
            return *this;
        }
    
        ComplexNumber& operator+=(const ComplexNumber& other) {
            real += other.real;
            imag += other.imag;
            return *this;
        }
    
        void display() const {
            std::cout << real << " + " << imag << "i" << std::endl;
        }
    };
    
    int main() {
        ComplexNumber num1(1.0, 2.0);
        ComplexNumber num2(3.0, 4.0);
    
        // Using the overloaded = and += operators
        num1 = num2 += ComplexNumber(5.0, 6.0);
    
        num1.display(); // 8 + 10i
    
        return 0;
    }