This article mainly introduces the difference between the copy constructor and assignment operator, and when to call the copy constructor and when to invoke the assignment operator. Finally, the problem of deep copy and shallow copy is simply analyzed.
Copy constructors and assignment operators
By default (the user is not defined, but there is no explicit deletion), the compiler automatically implicitly generates a copy constructor and assignment operator. However, users can use delete to specify that no copy constructors and assignment operators are generated, and such objects cannot be passed by value or assignment operations.
Class person
{public
: Person
(const person& p) = delete;
person& operator= (const person& p) = delete;
Private:
int age;
string name;
};
The above defined class person explicitly deletes the copy constructor and assignment operator, and prompts _ to call the copy constructor or assignment operator where it is called, which is a deleted function _.
It is also important to note that the copy constructor must pass parameters in a reference way . This is because when a value is passed to a function, the arguments of the copy constructor generation function are invoked. If the parameter of the copy constructor is still a value, it will be called indefinitely until the function stack overflows.
When to call
The behavior of the copy constructor and the assignment operator is quite similar, is to copy the value of one object to another, but the result is somewhat different, and the copy constructor uses the value of the Passed-in object to generate an instance of the new object, and the assignment operator is to copy the value of the object to an existing instance. This distinction can be easily distinguished from the names of both, and the copy constructor is also a constructor, and its function is to create a new object instance; An assignment operator performs an operation that copies the value of one object to another object (already existing). whether a copy constructor or an assignment operator is invoked, primarily to see if a new object instance is generated. If a new object instance is generated, then the copy constructor is invoked, and if not, it is assigning a value to an existing object and invoking an assignment operator.
The call copy constructor mainly has the following scenarios:
- Object as a function parameter, passed to the function in the form of a value.
- Object as the return value of the function, returning from the function as a value
- Class with one object for another object.
The code is as follows:
Class person
{public
: Person
() {} person
(const person& p)
{
cout <<] Copy Constructor "<< Endl;
}
person& operator= (const person& p)
{
cout << "Assign" << Endl;
return *this;
}
Private:
int age;
string name;
};
void f (person p)
{return
;
}
Person F1 ()
{person
p;
return p;
}
int main ()
{person
p;
person P1 = P; 1 person
p2;
P2 = p; 2
F (p2);//3
P2 = f1 ();//4 person
p3 = f1 ();//5
GetChar ()
; return 0;
}
The code above defines a class person, which explicitly defines the copy constructor and assignment operator. Then two functions are defined: F, the value of the parameter to the person object, F1, to return the person object in a value way. In main, the scene in 5 is modeled, and the test calls a copy constructor or an assignment operator. The results of the implementation are as follows:
The analysis is as follows:
- This is although "=" is used, but the object P is actually used to create a new object P1. That is, a new object is generated, so the copy constructor is invoked.
- Declare an object P2 first, then use the assignment operator "=" to copy the value of P to P2, apparently by invoking the assignment operator to assign a value to an already existing object.
- P2 the object into function f in a value pass, calling the copy constructor to construct an argument that is available for the function F.
- Both the copy constructor and the assignment operator of this statement are called. Function F1 returns a person object as a value, and when returned, the copy constructor is invoked to create a temporary object, TMP, as the return value, and the assignment operator is called to assign the temporary object tmp to P2.
- As explained in 4, the copy constructor should be called first to create a temporary object, and then the copy constructor is invoked to create a new object P3 with the temporary object just created, that is, a two copy constructor is invoked. However, the compiler is not so stupid, it should be directly called the copy constructor uses the return value to create the object p3.
Deep copy, Shallow copy
When it comes to copy constructors, you have to make deep copies and shallow copies. Typically, the default generated copy constructors and assignment operators are simply replicated for values. For example: The person class above, the field is only int and string two types, which are copied or assigned when the value of the copy created by the object and the source object is also no association, any action on the source object will not affect the copied objects. Conversely, if a person has an object with an int *, then the copy is copied only, then the value of the int * of the created Person object is the same location as the int * of the source object. Any modification of this value by an object affects another object, which is a shallow copy.
Deep and shallow copies are primarily for pointers and dynamically allocated space in a class, because the pointer is simply a copy of the value and cannot split the association of two objects, and any object's operation on that pointer will affect the other object. At this point, you need to provide a custom copy of the deep copy of the constructor to eliminate this effect. The usual principles are:
- A member with a pointer type or a member with dynamically allocated memory should provide a custom copy constructor
- While providing a copy constructor, you should also consider implementing a custom assignment operator
For the implementation of the copy constructor, make sure that the following points are:
- Value replication for members of value types
- For pointers and dynamically allocated space, allocation space should be reassigned in the copy
- For a base class, to invoke the appropriate copy method of the base class, complete the copy of the base class
Summarize
- The behavior of the copy constructor and the assignment operator is similar, but produces a different result; the copy constructor creates a new object with an existing object, and the assignment operator is to copy the value of one object to another existing object. The distinction is between calling a copy constructor or an assignment operator, or whether a new object is generated.
- About deep copies and shallow copies. A custom copy constructor should be implemented when the class has pointer members or has dynamic allocation space. The copy constructor is provided, and finally the assignment operator is implemented.
The above is the entire content of this article, I hope the content of this article for everyone's study or work can bring some help, if there are questions you can message exchange, but also hope that a lot of support cloud Habitat community!