Copy and Swap Idiom in C++



The Copy and Swap Idiom in C++ is a technique used in assignment operations. This consists of two steps: Discarding an object's old state and building a new state for it. The destructor is used for the first step and a copy constructor does the second step.

Implementing both of these is straightforward. But when overloading the assignment operator, it can become quite difficult to implement. The copy and swap idiom is a solution for the same.

This idiom uses the copy-constructor to build a local copy of the data. It then swaps the old data with the new data using the swap function. The temporary copy is then destructed using the destructor. We finally have only a copy of the new data.

So, the copy-and-swap idiom needs four things

  • copy-constructor: The copy constructor creates a deep copy.
  • destructor: The destructor releases memory of temporary copy after swap.
  • swap function: The swap function exchanges contents without causing exception.
  • copy-assignment: Implementing via copy and swap idiom

Note: You mustn't use the std:: swap function as it internally uses copy constructor and assignment operator to achieve the same.

Syntax

The syntax is as follows:

ClassName& operator=(ClassName other) {
    swap(*this, other);
    return *this;
}

Below are the two important programs that demonstrate the Copy and Swap Idiom in C++.

Copy and Swap Idiom Using Class

The Copy and Swap Idiom in a class means updating an object by copying new data and swapping it with the old data.

Example

In this example, we create a dynamic array class that assigns one object to another using the Copy and Swap Idiom, and prints the array values before and after assignment.

#include<iostream>
#include<algorithm>
using namespace std;
class MyArray {
   int* data;
   size_t size;
public:
   // Constructor
   MyArray(size_t s) : size(s) {
      data = new int[size];
      for (size_t i = 0; i<size; ++i)
         data[i] = i + 1;
   }   
   // Destructor
   ~MyArray() {
      delete[] data;
   }
   // Copy Constructor
   MyArray(const MyArray& other) : size(other.size) {
      data = new int[size];
      for (size_t i = 0; i<size; ++i)
         data[i] = other.data[i];
   }   
   // Swap Function (no-throw)
   friend void swap(MyArray& a, MyArray& b) noexcept {
      swap(a.data, b.data);
      swap(a.size, b.size);
   }  
   // Copy Assignment Operator using Copy-and-Swap Idiom
   MyArray& operator=(MyArray other) {
      swap(*this, other);
      return *this;
   }   
   void display() const {
      for (size_t i = 0; i < size; ++i)
         cout<<data[i]<<" ";
      cout<<endl;
   }
};
int main(){
   MyArray a(6);
   MyArray b(4); 
   cout<<"Before assignment:"<<endl;
   cout<<"a: "; a.display();
   cout<<"b:";b.display();
   b = a;  // uses copy and swap
   cout<<"\nAfter assignment(b = a):"<<endl;
   cout<<"a:";a.display();
   cout<<"b:";b.display();
   return 0;
}

Output

The above program produces the following result:

Before assignment:
a: 1 2 3 4 5 6
b: 1 2 3 4

After assignment (b = a):
a: 1 2 3 4 5 6
b: 1 2 3 4 5 6

Copy and Swap Idiom Using String Wrapper

Here, it copies and swaps the usage in a class that wraps a C-style string.

Example

In this example, we define a string wrapper class that assigns one object to another using the Copy and Swap Idiom and print the result.

#include<iostream>
#include<cstring>
using namespace std;
class StringWrapper{
   char* str;
public:
   // Constructor
   StringWrapper(const char* s = "") {
       str = new char[strlen(s) + 1];
       strcpy(str, s);
   }
   // Destructor
   ~StringWrapper() {
       delete[] str;
   }
   // Copy Constructor
   StringWrapper(const StringWrapper& other) {
       str = new char[strlen(other.str) + 1];
       strcpy(str, other.str);
   }

   // Swap Function (no-throw)
   friend void swap(StringWrapper& a, StringWrapper& b) noexcept {
       std::swap(a.str, b.str);
   }
   // Copy Assignment using Copy-and-Swap Idiom
   StringWrapper& operator=(StringWrapper other) {
       swap(*this, other);
       return *this;
   }
   void show() const {
       cout<<"String: "<<str<<endl;
   }
};
int main() {
   StringWrapper s1("Hello");
   StringWrapper s2("World");
   cout<<"Before assignment:"<<endl;
   s1.show();
   s2.show();
   s2 = s1;
   cout<<"\nAfter assignment(s2=s1):"<<endl;
   s1.show();
   s2.show();
   return 0;
}

Output

The above program produces the following result:

Before assignment:
String: Hello
String: World

After assignment(s2=s1):
String: Hello
String: Hello
Revathi Satya Kondra
Revathi Satya Kondra

Technical Content Writer, Tutorialspoint

Updated on: 2025-04-22T19:08:35+05:30

286 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements