Copy constructor
Encyclopedia
A copy constructor is a special constructor
in the C++
programming language
creating a new object
as a copy
of an existing object. The first argument of such a constructor is a reference to an object of the same type as is being constructed (const or non-const), which might be followed by parameters of any type (all having default values).
Normally the compiler
automatically creates a copy constructor for each class
(known as a default copy constructor) but for special cases the programmer
creates the copy constructor, known as a user-defined copy constructor. In such cases, the compiler does not create one. Hence, there is always one copy constructor that is either defined by the user or by the system.
A user-defined copy constructor is generally needed when an object owns pointers
or non-shareable references
, such as to a file
, in which case a destructor
and an assignment operator
should also be written (see Rule of three
).
. A copy constructor has as its first parameter a (possibly const or volatile
) reference
to its own class type. It can have more arguments, but the rest must have default values associated with them. The following would be valid copy constructors for class
The first one should be used unless there is a good reason to use one of the others. One of the differences between the first and the second is that temporaries can be copied with the first. For example:
Another difference between them is the obvious:
The
The following are invalid copy constructors (Reason -
because the call to those constructors would require a copy as well, which would result in an infinitely recursive call.
The following cases may result in a call to a copy constructor:
These cases are collectively called copy-initialization and are equivalent to:
It is however, not guaranteed that a copy constructor will be called in these cases, because the C++ Standard allows the compiler to optimize the copy away in certain cases, one example being the return value optimization
(sometimes referred to as RVO).
a. Through declaration
b. Through function arguments
c. Through function return value
The copy constructor is used only for initializations, and does not apply to assignments where the assignment operator is used instead.
The implicit copy constructor of a class calls base copy constructors and copies its members by means appropriate to their type. If it is a class type, the copy constructor is called. If it is a scalar type, the built-in assignment operator is used. Finally, if it is an array, each element is copied in the manner appropriate to its type.
By using a user-defined copy constructor the programmer can define the behavior to be performed when an object is copied.
Output
10 15 10
23 15 10
As expected, timmy has been copied to the new object, timmy_clone. While timmy's age was changed, timmy_clone's age remained the same. This is because they are totally different objects.
The compiler has generated a copy constructor for us, and it could be written like this:
So, when do we really need a user-defined copy constructor? The next section will explore that question.
class like the following:
Output
25 25
Segmentation fault
Since we did not specify a copy constructor, the compiler generated one for us. The generated constructor would look something like:
The problem with this constructor is that it performs a shallow copy of the data pointer. It only copies the address of the original data member; this means they both share a pointer to the same chunk of memory, which is not what we want. When the program reaches line (1), copy's destructor gets called (because objects on the stack are destroyed automatically when their scope ends).
Array's destructor deletes the data array of the original, therefore when it deleted copy's data, because they share the same pointer, it also deleted first's data. Line (2) now accesses invalid data and writes to it! This produces the infamous segmentation fault
.
If we write our own copy constructor that performs a deep copy then this problem goes away.
Here, we are creating a new int array and copying the contents to it. Now, copy's destructor only deletes its data and not first's data as well. Line (2) will not produce a segmentation fault anymore.
Instead of doing a deep copy right away, there are some optimization strategies that can be used. These allow you to safely share the same data between several objects, thus saving space. The copy on write strategy makes a copy of the data only when it is written to. Reference counting
keeps the count of how many objects are referencing the data, and will delete it only when this count reaches zero (e.g. boost::shared_ptr).
(Note that the type of
It is clear from the above figure that in a bitwise copy constructor the original as well as the new object point to the same variable. Hence, the value of the variable is changed for both the objects even if it is changed by only one object.
It can be seen from the above figure that in a logical copy constructor, a new dynamic - member variable is created for the pointer along with copying the values.
It is used to prevent copying of objects at function calls or with the copy-initialization syntax.
Constructor (computer science)
In object-oriented programming, a constructor in a class is a special type of subroutine called at the creation of an object. It prepares the new object for use, often accepting parameters which the constructor uses to set any member variables required when the object is first created...
in the C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
programming language
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
creating a new object
Object (computer science)
In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...
as a copy
Object copy
An object copy is an action in computing where a data object has its attributes copied to another object of the same data type. An object is a composite data type in object-oriented programming languages. The copying of data is one of the most common procedures that occurs in computer programs...
of an existing object. The first argument of such a constructor is a reference to an object of the same type as is being constructed (const or non-const), which might be followed by parameters of any type (all having default values).
Normally the compiler
Compiler
A compiler is a computer program that transforms source code written in a programming language into another computer language...
automatically creates a copy constructor for each class
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
(known as a default copy constructor) but for special cases the programmer
Programmer
A programmer, computer programmer or coder is someone who writes computer software. The term computer programmer can refer to a specialist in one area of computer programming or to a generalist who writes code for many kinds of software. One who practices or professes a formal approach to...
creates the copy constructor, known as a user-defined copy constructor. In such cases, the compiler does not create one. Hence, there is always one copy constructor that is either defined by the user or by the system.
A user-defined copy constructor is generally needed when an object owns pointers
Data pointer
In computer science, a pointer is a programming language data type whose value refers directly to another value stored elsewhere in the computer memory using its address...
or non-shareable references
Reference (computer science)
In computer science, a reference is a value that enables a program to indirectly access a particular data item, such as a variable or a record, in the computer's memory or in some other storage device. The reference is said to refer to the data item, and accessing those data is called...
, such as to a file
Computer file
A computer file is a block of arbitrary information, or resource for storing information, which is available to a computer program and is usually based on some kind of durable storage. A file is durable in the sense that it remains available for programs to use after the current program has finished...
, in which case a destructor
Destructor (computer science)
In object-oriented programming, a destructor is a method which is automatically invoked when the object is destroyed...
and an assignment operator
Assignment operator in C++
In the C++ programming language, the assignment operator, '=', is the operator used for assignment. Like most other operators in C++, it can be overloaded....
should also be written (see Rule of three
Rule of three (C++ programming)
The rule of three is a rule of thumb in C++ that claims that if a class defines one of the following it should probably explicitly define all three:*destructor*copy constructor*assignment operator...
).
Definition
Copying of objects is achieved by the use of a copy constructor and an assignment operatorAssignment operator in C++
In the C++ programming language, the assignment operator, '=', is the operator used for assignment. Like most other operators in C++, it can be overloaded....
. A copy constructor has as its first parameter a (possibly const or volatile
Volatile variable
In computer programming, particularly in the C, C++, C#, and Java programming languages, a variable or object declared with the volatile keyword usually has special properties related to optimization and/or threading...
) reference
Reference (C++)
In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C...
to its own class type. It can have more arguments, but the rest must have default values associated with them. The following would be valid copy constructors for class
X
:The first one should be used unless there is a good reason to use one of the others. One of the differences between the first and the second is that temporaries can be copied with the first. For example:
Another difference between them is the obvious:
The
X&
form of the copy constructor is used when it is necessary to modify the copied object. This is very rare but it can be seen used in the standard library's std::auto ptr
. A reference must be provided:The following are invalid copy constructors (Reason -
copy_from_me
is not passed as reference) :because the call to those constructors would require a copy as well, which would result in an infinitely recursive call.
The following cases may result in a call to a copy constructor:
- When an object is returned by value
- When an object is passed (to a function) by value as an argument
- When an object is thrown
- When an object is caught
- When an object is placed in a brace-enclosed initializer list
These cases are collectively called copy-initialization and are equivalent to:
T x = a;
It is however, not guaranteed that a copy constructor will be called in these cases, because the C++ Standard allows the compiler to optimize the copy away in certain cases, one example being the return value optimization
Return value optimization
Return value optimization, or simply RVO, is a compiler optimization technique that involves eliminating the temporary object created to hold a function's return value...
(sometimes referred to as RVO).
Operation
An object can be assigned value using one of the two techniques:- Explicit assignment in an expression
- Initialization
Explicit assignment in an expression
Initialization
An object can be initialized by any one of the following ways.a. Through declaration
b. Through function arguments
c. Through function return value
The copy constructor is used only for initializations, and does not apply to assignments where the assignment operator is used instead.
The implicit copy constructor of a class calls base copy constructors and copies its members by means appropriate to their type. If it is a class type, the copy constructor is called. If it is a scalar type, the built-in assignment operator is used. Finally, if it is an array, each element is copied in the manner appropriate to its type.
By using a user-defined copy constructor the programmer can define the behavior to be performed when an object is copied.
Examples
These examples illustrate how copy constructors work and why they are required sometimes.Implicit copy constructor
Let us consider the following example.Output
10 15 10
23 15 10
As expected, timmy has been copied to the new object, timmy_clone. While timmy's age was changed, timmy_clone's age remained the same. This is because they are totally different objects.
The compiler has generated a copy constructor for us, and it could be written like this:
So, when do we really need a user-defined copy constructor? The next section will explore that question.
User-defined copy constructor
Now, consider a very simple dynamic arrayDynamic array
In computer science, a dynamic array, growable array, resizable array, dynamic table, or array list is a random access, variable-size list data structure that allows elements to be added or removed...
class like the following:
Output
25 25
Segmentation fault
Since we did not specify a copy constructor, the compiler generated one for us. The generated constructor would look something like:
The problem with this constructor is that it performs a shallow copy of the data pointer. It only copies the address of the original data member; this means they both share a pointer to the same chunk of memory, which is not what we want. When the program reaches line (1), copy's destructor gets called (because objects on the stack are destroyed automatically when their scope ends).
Array's destructor deletes the data array of the original, therefore when it deleted copy's data, because they share the same pointer, it also deleted first's data. Line (2) now accesses invalid data and writes to it! This produces the infamous segmentation fault
Segmentation fault
A segmentation fault , bus error or access violation is generally an attempt to access memory that the CPU cannot physically address. It occurs when the hardware notifies an operating system about a memory access violation. The OS kernel then sends a signal to the process which caused the exception...
.
If we write our own copy constructor that performs a deep copy then this problem goes away.
Here, we are creating a new int array and copying the contents to it. Now, copy's destructor only deletes its data and not first's data as well. Line (2) will not produce a segmentation fault anymore.
Instead of doing a deep copy right away, there are some optimization strategies that can be used. These allow you to safely share the same data between several objects, thus saving space. The copy on write strategy makes a copy of the data only when it is written to. Reference counting
Reference counting
In computer science, reference counting is a technique of storing the number of references, pointers, or handles to a resource such as an object, block of memory, disk space or other resource...
keeps the count of how many objects are referencing the data, and will delete it only when this count reaches zero (e.g. boost::shared_ptr).
Copy constructors and templates
Contrary to expectations, a template copy constructor is not a user-defined copy constructor. Thus it is not enough to just have:(Note that the type of
A
can be Array
.) A user-defined, non-template copy constructor must also be provided for construction of Array from Array.Bitwise Copy Constructor
A bitwise copy constructor performs a simple variable - by - variable assignment copy of all the components of an object. The bitwise copy constructor is so named as it merely copies bit - by - bit from the original object to the new object.It is clear from the above figure that in a bitwise copy constructor the original as well as the new object point to the same variable. Hence, the value of the variable is changed for both the objects even if it is changed by only one object.
Logical Copy Constructor
A logical copy constructor makes a true copy of the structure as well as its dynamic structures. Logical copy constructor come into picture mainly when there are pointers or complex objects, within the object.It can be seen from the above figure that in a logical copy constructor, a new dynamic - member variable is created for the pointer along with copying the values.
Explicit copy constructor
An explicit copy constructor is one that is declared explicit by using the explicit keyword. For example:It is used to prevent copying of objects at function calls or with the copy-initialization syntax.