Copy constructor

(1) Why copy constructors?

There are three ways to pass parameters to a function
One is to transfer values, one is to transfer addresses, and the other is to transfer references.
The difference between value passing and other two methods is that when the value passing method is used, it will be generated in the functionTransfer parametersThe contents of the copy are copied bit by bit from the original parameter. The contents of the two are the same.

When the original parameter is an object of a class, it will also produce a copy of the object. At this time, we need to pay attention to: generally, when creating an object, the constructor will be called to initialize it. However, if the constructor of the object is executed again when the copy of the object is produced, the properties of the object will be restored to the original state again. This is not what we want. thereforeWhen a copy of an object is generated, the constructor is not executed. Instead, a default copy constructor is executed.

If a copy constructor is not declared in the class, the compiler implicitly defines a default copy constructor for you.

When the copy constructor is called:

  1. An object is passed into the function body by value passing
  2. An object is returned from a function by value passing
  3. One object needs to be initialized by another object

(2) Why write your own copy constructor

When the function is completed and returned, the object copy will execute the destructor. If your destructor is empty, there will be no problem. However, the general destructor needs to complete some cleaning work, such as releasing the memory space pointed by the pointer. At this time, there may be a problem.

b->p = a->p; 
The int \ * P pointer in B points to the memory of the application pointed by int \ * P in a  
Two pointers point to the same heap memory

We allocate memory for a pointer variable in the constructor, and release the memory space pointed to by the pointer in the destructor. In the process of passing the object to the function and returning it at the end of the function:
First, a copy of the object is generated. This copy also has a pointerIt points to the same block of memory space as the pointer to the original objectWhen the function returns, the destructor of the replica object executes, freeing the memory space pointed by the pointer in the replica object, but this memory space is still valid for the original object.

A - > P becomes a null pointer, which is the first problem.
When the original object is also destroyed, the destructor of the original object will be executed, and the memory space that has been released will be released again, resulting in serious errors. This is the second problem.


Since there is such a problem in value transfer, can we use address transfer or reference transfer to solve this problem? In fact, uploading address and transferring reference can solve this problem, but it does not apply to all cases. Sometimes we do not want some operations inside the function to affect variables outside the function.

In order to solve this problem, we need to write the copy constructor. The copy constructor is executed when the copy object is generated. In the copy constructor, we apply for a new memory space, so that when the copy object executes the destructor, it releases the new memory space, so as to solve this problem.

If you don’t want to use the pass by value object, you don’t need the copy constructor, but if we don’t write the copy constructor, the compiler may create a default one for us. So how to ensure that an object will never be passed by value passing? Declare a private copy constructor, and you don’t even have to define it, unless member or friend functions need to perform value passing. Otherwise, if the user attempts to pass or return an object by value, the compiler will report an error.