How to Utilize the Copy Constructor in C++

Jinku Hu Feb 02, 2024
  1. Use the Copy Constructor to Initialize an Object from Another Object of the Same Type in C++
  2. Use the Copy Assignment Operator to Define the Assignment Operator Overload for the Object in C++
How to Utilize the Copy Constructor in C++

This article explains several methods of how to utilize a copy constructor in C++.

Use the Copy Constructor to Initialize an Object from Another Object of the Same Type in C++

There are several operations in the class collectively called copy control. These operations define how the objects of the given class type are copied, moved, assigned, or destroyed. In this article, we’ll only focus on the copy constructor and copy assignment.

The copy constructor initializes the object by duplicating the value of the argument passed as the reference (it’s commonly passed as the const reference). The class is not required to define copy constructor as any other copy control operations because the compiler automatically defines synthesized operations for undefined ones. Still, often the latter ones might cause problems. The synthesized copy constructor copies each member of the argument object to the object that’s being created. There might be members of some other class types, which get copied by their copy constructor. In contrast, built-in type objects are copied directly.

The following example code demonstrates the behavior of the copy constructor of the MyClass, which takes the only mandatory argument for the copy constructor and then initializes data members. On the other hand, the copy constructor can have additional arguments, which must be optional and have default values.

When the object of type MyClass is created at first, the default constructor is invoked; however, if we assign m1 to the newly created m3 variable, the copy constructor is called. The latter operation is also called copy initialization, which may utilize a copy constructor or move a constructor (discussed in another article).

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Output:

Constructor 1 is called
------------------
Constructor 1 is called
------------------
Copy Constructor is called
------------------
1221
1133
1221

Use the Copy Assignment Operator to Define the Assignment Operator Overload for the Object in C++

The copy assignment operator defines how to assign objects of the same type. The compiler also synthesizes this operation if the user does not define it explicitly. Copy assignment is described similarly to other operator overloading functions. It takes an argument of the same type as the class and usually returns the reference to the left-hand operand. A copy assignment operator must be defined as a member function.

The next code snippet adds the copy assignment operator for the MyClass and invokes it while assigning the m2 object to the m1.

#include <iostream>

using std::cout;
using std::endl;
using std::pair;

class MyClass {
 private:
  int n1{};
  int n2{};

 public:
  MyClass(int x, int y) : n1(x), n2(y) {
    cout << "Constructor 1 is called" << endl;
  };

  MyClass(const MyClass& src) {
    cout << "Copy Constructor is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
  }

  MyClass& operator=(const MyClass& src) {
    cout << "Copy Assignment is called " << endl;
    n1 = src.n1;
    n2 = src.n2;
    return *this;
  }

  auto getPair() { return pair<int, int>(n1, n2); }

  ~MyClass() = default;
};

int main() {
  MyClass m1(12, 21);
  cout << "------------------" << endl;
  MyClass m2(11, 33);
  cout << "------------------" << endl;
  MyClass m3 = m1;
  cout << "------------------" << endl;
  m1 = m2;
  cout << "------------------" << endl;

  cout << m1.getPair().first << m1.getPair().second << endl;
  cout << m2.getPair().first << m2.getPair().second << endl;
  cout << m3.getPair().first << m3.getPair().second << endl;

  return EXIT_SUCCESS;
}

Output:

Constructor 1 is called
------------------
Constructor 1 is called
------------------
Copy Constructor is called
------------------
Copy Assignment is called
------------------
1221
1133
1221
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Constructor