Copy Constructors in C++


The Copy Constructor

The constructor that takes a single parameter that is a (usually const) reference to an object of the class type itself is called the copy constructor.

When Copy Constructors Are Used

The copy constructor can be implicitly invoked by the complier. The copy constructor is used in following cases.

  • Explicitly or implicitly initialize one object from another of the same type.

C++ supports two forms of initialization: direct and copy. Direct initialization directly invokes the constructor matched by the arguments. Copy initialization first use the constructor to create a temporary object, it then uses the copy constructor to copy that temporary object into the one we are creating.

1
2
3
4
5
6
7
8
9
10
11
12
13
// copy initialization: first create a temporary by invoking the string constructor, 
// then uses the string copy construcor to initialize null_book as a copy of that temporary
string null_book = "9-999-99999-9";  

// direct initialization
string dots(10, '.');  

// copy initialization: the default constructor creates a temporary object, 
// which is then used by the copy constructor to initialize empty_copy
string empty_copy = string();  

// direct initialization
string empty_direct;  
  • Copy an object to pass it as an argument to a function.
1
bool isShorter(string s1, string s2);
  • Copy an object to return it from a function.
1
2
3
// copy constructor used to copy the return value;
// parameters are references, so they aren't copied
string make_plural(size_t, const string&, const string&);
  • Initialize the elements in a sequential container.
1
2
// default string constructor and five string copy constructors invoked
vector<string> svec(5);
  • Initialize elements in an array from a list of element initializers.
1
2
3
4
Sales_item primer_eds[] = { string("0-201-16487-6"), 
                            string("0-201-54848-8"), 
                            string("0-201-82470-1"),
                          };

Define Our Own Copy Constructor

For many classes, the default copy constructor does exactly the work that is needed. However, some classes must take control of what happens when objects are copied. Such classes often have a data member that is a pointer or that represents another resource that is allocated in the constructor. In these cases, the copy constructor must be defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>

using namespace std;

class NoName {
private:
    string *pstring;
    int i;
    double d;
public:
    NoName() {   // constructor
    	cout << "Constructor;" << endl;
    	pstring = new string();
    	i = 0;
    	d = 0;
    }  
    NoName(const NoName& nn) {   // copy constructor
    	cout << "Copy Constructor;" << endl;
        pstring = new string();
        *pstring = *nn.pstring;
        i = nn.i;
        d = nn.d;
    }
    ~NoName() {   // destructor
    	cout << "Destructor;" << endl;
    	delete pstring;
    }
    void setPstring(string &s) {
        *pstring = s;
    }
    void display() {
    	cout << *pstring << endl;
    }
};

int main() {
    NoName n1;
    string s = "hello";
    n1.setPstring(s);
    NoName n2 = n1;
    n1.display();
    n2.display();
}

The output of the above code is:

1
2
3
4
5
6
Constructor;
Copy Constructor;
hello
hello
Destructor;
Destructor;

However, if we comment out the copy constructor, the output of the above code will be:

1
2
3
4
5
6
7
Constructor;
hello
hello
Destructor;
Destructor;
free(): double free detected in tcache 2
Aborted

This is because if there is no copy constructor, when we assign n1 to n2, the pstring pointer in n2 will point to the same object as the pstring in n1. So both of n1 and n2’s destructors are trying to destroy the same object. If we add the copy constructor, we will allocate a new string pointer in n2. The two destructors will destroy its own string pointer object.




Related Posts

Template Specializations in C++

A template specialization is a separate definition in which the...

Copy Constructors in C++

The constructor that takes a single parameter that is a...

Friend Class and Function in C++

A friend class can access private and protected members of...

Templates in C++

A template is a blueprint or formula for creating a...

Polymorphism in C++

Polymorphism means having more than one function with the same...

Interfaces in C++

An interface describes the behavior or capabilities of a C++...