13.1. 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. Like the default constructor, the copy constructor can be implicitly invoked by the compiler. The copy constructor is used toExplicitly or implicitly initialize one object from another of the same typeCopy an object to pass it as an argument to a functionCopy an object to return it from a functionInitialize the elements in a sequential containerInitialize elements in an array from a list of element initializers
Forms of Object Definition
Recall that C++ supports two forms of initialization (Section 2.3.3, p. 48): direct and copy. Copy-initialization uses the = symbol, and direct-initialization places the initializer in parentheses.The copy and direct forms of initialization, when applied to objects of class type, are subtly different. Direct-initialization directly invokes the constructor matched by the arguments. Copy-initialization always involves the copy constructor. Copy-initialization first uses the indicated constructor to create a temporary object (Section 7.3.2, p. 247). It then uses the copy constructor to copy that temporary into the one we are creating:
For objects of class type, copy-initialization can be used only when specifying a single argument or when we explicitly build a temporary object to copy.When dots is created, the string constructor that takes a count and a character is called and directly initializes the members in dots. To create null_book, the compiler first creates a temporary by invoking the string constructor that takes a C-style character string parameter. The compiler then uses the string copy constructor to initialize null_book as a copy of that temporary.The initialization of empty_copy and empty_direct both call the string default constructor. In the first case, the default constructor creates a temporary object, which is then used by the copy constructor to initialize empty_copy. In the second case, the default constructor is run directly on empty_direct.The copy form of initialization is primarily supported for compatibility with C usage. When it can do so, the compiler is permitted (but not obligated) to skip the copy constructor and create the object directly.Usually the difference between direct- or copy-initialization is at most a matter of low-level optimization. However, for types that do not support copying, or when using a constructor that is nonexplicit (Section 12.4.4, p. 462) the distinction can be essential:
string null_book = "9-999-99999-9"; // copy-initialization
string dots(10, '.'); // direct-initialization
string empty_copy = string(); // copy-initialization
string empty_direct; // direct-initialization
The initialization of file1 is fine. The ifstream class defines a constructor that can be called with a C-style string. That constructor is used to initialize file1.Section 8.1, p. 287), so we cannot use copy-initialization on objects of these types.Whether the initialization of item is okay depends on which version of our Sales_item class we are using. Some versions define the constructor that takes a string as explicit. If the constructor is explicit, then the initialization fails. If the constructor is not explicit, then the initialization is fine.
ifstream file1("filename"); // ok: direct initialization
ifstream file2 = "filename"; // error: copy constructor is private
// This initialization is okay only if
// the Sales_item(const string&) constructor is not explicit
Sales_item item = string("9-999-99999-9");
Parameters and Return Values
As we know, when a parameter is a nonreference type (Section 7.2.1, p. 230), the argument is copied. Similarly, a nonreference return value (Section 7.3.2, p. 247) is returned by copying the value in the return statement.When the parameter or return type is a class type, the copy is done by the copy constructor. For example, consider our make_plural function from page 248:
This function implicitly uses the string copy constructor to return the plural version of a given word. The parameters are const references; they are not copied.
// 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&);
Initializing Container Elements
The copy constructor is used to initialize the elements in a sequential container. For example, we can initialize a container using a single parameter that represents a size (Section 3.3.1, p. 92). This form of construction uses both the default constructor and the copy constructor for the element container:
The compiler initializes svec by first using the default string constructor to create a temporary value. The copy constructor is then used to copy the temporary into each element of svec.Section 9.1.1, p. 307), unless you intend to use the default initial value of the container elements, it is more efficient to allocate an empty container and add elements as the values for those elements become known.
// default string constructor and five string copy constructors invoked
vector<string> svec(5);
Constructors and Array Elements
If we provide no element initializers for an array of class type, then the default constructor is used to initialize each element. However, if we provide explicit element initializers using the normal brace-enclosed array initialization list (Section 4.1.1, p. 111), then each element is initialized using copy-initialization. An element of the appropriate type is created from the specified value, and then the copy constructor is used to copy that value to the corresponding element:
A value that can be used to invoke a single-argument constructor for the element type can be specified directly, as in the initializers for the first three elements. If we wish to specify no arguments or multiple arguments, we need to use the full constructor syntax, as we do in the initializer for the last element.
Sales_item primer_eds[] = { string("0-201-16487-6"),
string("0-201-54848-8"),
string("0-201-82470-1"),
Sales_item()
};
Exercises Section 13.1
[View full width]vector<int> v1(42); // ok: 42 elements, each 0
vector<int> v2 = 42; // error: what does this error tell us

Exercise 13.3:Assuming Point is a class type with a public copy constructor, identify each use of the copy constructor in this program fragment:
Point global;
Point foo_bar(Point arg)
{
Point local = arg;
Point *heap = new Point(global);
*heap = local;
Point pa[ 4 ] = { local, *heap };
return *heap;
}
13.1.1. The Synthesized Copy Constructor
If we do not otherwise define the copy constructor, the compiler synthesizes one for us. Unlike the synthesized default constructor (Section 12.4.3, p. 458), a copy constructor is synthesized even if we define other constructors. The behavior of the synthesized copy constructor is to memberwise initialize the new object as a copy of the original object.By memberwise, we mean that taking each nonstatic member in turn, the compiler copies the member from the existing object into the one being created. With one exception, the type of each member determines what it means to copy it. The synthesized copy constructor directly copies the value of members of built-in type. Members of class type are copied by using the copy constructor for that class. The one exception concerns array members. Even though we ordinarily cannot copy an array, if a class has a member that is an array, then the synthesized copy constructor will copy the array. It does so by copying each element.The simplest conceptual model of memberwise initialization is to think of the synthesized copy constructor as one in which each data member is initialized in the constructor initializer list. For example, given our Sales_item class, which has three data members
the synthesized Sales_item copy constructor would look something like:
class Sales_item {
// other members and constructors as before
private:
std::string isbn;
int units_sold;
double revenue;
};
Sales_item::Sales_item(const Sales_item &orig):
isbn(orig.isbn), // uses string copy constructor
units_sold(orig.units_sold), // copies orig.units_sold
revenue(orig.revenue) // copy orig.revenue
{ } // empty body
13.1.2. Defining Our Own Copy Constructor
The copy constructor is the constructor that takes a single parameter that is a (usually const) reference to the class type:
Usually the parameter is a const reference, although we can also define the copy constructor to take a nonconst reference. Because the constructor is used (implicitly) to pass and return objects to and from functions, it usually should not be made explicit (Section 12.4.4, p. 462). The copy constructor should copy the members from its argument into the object that is being constructed.For many classes, the synthesized copy constructor does exactly the work that is needed. Classes that contain only members that are of class type or members that are of built-in (but not pointer type) often can be copied without explicitly defining the copy constructor.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. Other classes have bookkeeping that must be done whenever a new object is created. In both these cases, the copy constructor must be defined.Section 13.4 (p. 486) looks at a pair of classes that require an explicit copy constructor to handle bookkeeping associated with a simple message-handling application; classes with members that are pointers are covered in Section 13.5 (p. 492).
class Foo {
public:
Foo(); // default constructor
Foo(const Foo&); // copy constructor
// ...
};
Exercises Section 13.1.2
Exercise 13.4:Given the following sketch of a class, write a copy constructor that copies all the elements. Copy the object to which pstring points, not the pointer.
Exercise 13.5:Which class definition is likely to need a copy constructor?
struct NoName {
NoName(): pstring(new std::string), i(0), d(0) { }
private:
std::string *pstring;
int i;
double d;
};
- A Point3w class containing four float membersA Matrix class in which the actual matrix is allocated dynamically within the constructor and is deleted within its destructorA Payroll class in which each object is provided with a unique IDA Word class containing a string and a vector of line and column location pairs
Sales_item::Sales_item(const Sales_item rhs);
13.1.3. Preventing Copies
Some classes need to prevent copies from being made at all. For example, the iostream classes do not permit copying (Section 8.1, p. 287). It might seem that if we want to forbid copies, we could omit the copy constructor. However, if we don't define a copy constructor, the compiler will synthesize one.

Most Classes Should Define Copy and Default Constructors
Classes that do not define the default constructor and/or the copy constructor impose serious limits on users of the class. Objects of classes that do not allow copies may be passed to (or returned from) a function only as a reference. They also may not be used as elements in a container.
