Open In App

Copy-and-Swap Idiom in C++

Last Updated : 04 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In C++, classes that manage dynamic resources requires assignment operator overloading for deep copying the data of assigned objects. Copy Swap Idiom is an efficient technique to overload the assignment operator and provides several benefits over normal overloading method.

Problems with Normal Assignment Operator Overloading

Before discussing copy swap idiom in C++, let us first have a look on the normal overloaded assignment operator that we use:

CPP
class GfG {
    int size;
    int* ptr;
public:
    GfG(int s = 0) {
        size = s;
        ptr = (size < 0) ? new int[size] : nullptr;
    }

    // Copy constructor
    GfG(const GfG& obj) {
        size = obj.size;
        this->ptr = (size < 0) ? new int[size] : nullptr;
        copy(obj.ptr, ojb.ptr + size, this->ptr);
    }

    // Overloaded assignment operator
    GfG& operator=(const GfG& obj) {
        
        // Self assignment check
        if (this != &obj) {
            
            // Delete previous memory
            delete [] this->ptr;
            
            // Allocate new memory
            this->ptr = new int[obj.size];
                
            // Copy object
            this->size = obj.size;
            memmove(this->ptr, obj.ptr, this->size * sizeof(int));
        }
        return *this;
    }
    
    ~GfG() { delete[] ptr; }
};

In the above class, assignment operator does the following things:

  1. Performs a self-assignment check.
  2. If the assignment is not to self, then it does the following:
    • Deallocates memory assigned to this->ptr.
    • Allocates new memory to this->ptr.
    • Copies the new data.
  3. Finally, it returns *this.

There are few drawbacks of this approach:

  • Self-Assignment Check: Self allocation is done very rarely, so it is not relevant in most of the scenarios. This just slows down the code.
  • Memory Deallocation and Allocation: As it can be seen that first, the memory is deallocated (leaving the pointer dangling) and then the new chunk of memory is allocated. Now if due to some reason the memory is not allocated, and an exception is thrown, then the this->ptr will be left dangling pointing to a deallocated memory. The scenario should be either the assignment is successful, or the object should not be altered at all.
  • Code Duplication: The core logic of the assignment operator overloading (copying the actual data) is already written in the copy constructor of the class.

The first two drawbacks can be handled by adding additional checks, but it increases the size of the code and still doesn't handle the code duplication. Here comes the role of copy-and-swap approach.

Copy and Swap Idiom

The copy-swap idiom elegantly solves the above issue in normal assignment operator overloading and also provides a scope for code re-usability. It uses the copy constructor to first create a temporary copy of the object and then swap resources of current object using swap() function. The previous resources swapped with the temporary copy gets deleted when the operator function returns.

Example:

CPP
#include <bits/stdc++.h>
using namespace std;

class GfG {
    int size;
    int* ptr;
public:
    GfG(int s = 0) {
        size = s;
        ptr = (size < 0) ? new int[size] : nullptr;
    }

    // Copy constructor
    GfG(const GfG& obj) {
        size = obj.size;
        ptr = (size < 0) ? new int[size] : nullptr;
        copy(obj.ptr, ojb.ptr + size, this->ptr);
    }

    // Defining a swap function
    friend void swap(GfG& obj1, GfG& obj2) {
        swap(obj1.size, obj2.size);
        swap(obj1.ptr, obj2.ptr);
    }

    // Overloaded assignment operator
    // Argument passed by value
    GfG& operator= (GfG obj) {
        
        // Swapping resources
        swap(*this, obj);
        return *this;
    }

    ~GfG() { delete[] ptr; }
};

See how small the code for assignment operator overload has become. Let's break down how it achieves its functionality:

  1. Other object is passed by value to the operator function, means that a local copy of it will be created by calling copy constructor.
  2. The swap function swaps the resources, which means that the current object will swap its resources with the local copy of obj.
  3. When the operator function returns *this, the local copy of obj, which is not containing the previous resources of this object, will be destroyed automatically.

Copy swap idiom provides the following advantages over the normal assignment operator overloading:

  1. No more self-assignment check needed as the parameter is passed by value. Moreover, as self-allocation is very rare so the overhead of copying in case of self-assignment should not be a problem.
  2. Now as copy constructor is used to create the obj object, therefore the swapping will only be done if the obj object is at all created. Basically, what we were doing manually there, the compiler is doing it for us in here.
  3. As we can see the operator=() does not have much code in its body rather, we are using the copy constructor and swap function to do the job.

Article Tags :
Practice Tags :

Similar Reads