Copy constructors and value assignment operators
Author: Feng Mingde
Note: classes that contain dynamically assigned members should provide copy constructors and overload the "=" value assignment operator.
The following examples will be used:
Class cexample {public: cexample () {pbuffer = NULL; nsize = 0 ;}~ Cexample () {Delete pbuffer;} void Init (int n) {pbuffer = new char [N]; nsize = N;} PRIVATE: char * pbuffer; // The class object contains a pointer pointing to the dynamically allocated memory resource int nsize ;};
The main feature of this class is to include pointers to other resources.
Pbuffer points to a memory space allocated in the heap.
I. copy constructors
Int main (INT argc, char * argv []) {cexample theobjone; theobjone. init40); // now another object is required, and the State cexample theobjtwo = theobjone;...} must be initialized ;...}
Statement "cexample theobjtwo = theobjone;" use theobjone to initialize theobjtwo.
The complete method is to copy the values of all members in the memory.
After completion, theobjtwo. pbuffer = theobjone. pbuffer.
That is, they will point to the same place. Although the pointer is copied, the space to which it points is not copied, but shared by two objects. In this way, the objects are not independent, and the deletion of spaces poses a risk.
Therefore, necessary measures are required to avoid such situations.
Review the specific process of the following statement: first, create the object theobjtwo, call its constructor, and then the Member is copied.
You can add operations in the constructor to solve the problem of pointer members.
Therefore, in addition to providing default constructor, C ++ also standardizes another special constructor: copy constructor. In the preceding statement, if a copy constructor is defined in the class, when the object is created, the copy constructor is called. In the copy constructor, you can refer to the input variables, copy the resource pointed to by the pointer.
The format of the copy constructor is: constructor name (Object reference)
The cexample class provided after the copy constructor is defined:
Class cexample {public: cexample () {pbuffer = NULL; nsize = 0 ;}~ Cexample () {Delete pbuffer;} cexample (const cexample &); // copy the constructor void Init (int n) {pbuffer = new char [N]; nsize = N ;} PRIVATE: char * pbuffer; // class object contains pointer, pointing to the dynamically allocated memory resource int nsize ;}; cexample: cexample (const cexample & rightsides) // copy the definition of the constructor {nsize = rightsides. nsize; // copy the regular member pbuffer = new char [nsize]; // copy the content memcpy (pbuffer, rightsides. pbuffer, nsize * sizeof (char ));}
In this way, when a new object is defined and initialized with an existing object, cexample (const cexample & rightsides) will be called, and the existing object will be passed to the constructor using the alias rightsides for copying.
In principle, a copy constructor should be provided for all classes that contain dynamically assigned members.
Another method of calling the copy constructor.
When an object is directly transmitted as a parameter to the function, the function will create a temporary copy of the object. This copy process will also be called the same copy constructor.
For example
Bool testfunc (cexample OBJ); testfunc (theobjone); // The object is directly used as a parameter. Bool testfunc (cexample OBJ) {// operations on OBJ are actually performed on temporary copies after replication}
Another case is also related to temporary objects.
When a local object in the function is returned to the function caller, a temporary copy of the local object will also be created, and the copy constructor will also be called.
Ctest func () {ctest thetest; return thetest}
Ii. overload of value assignment
The followingCodeSimilar to the previous example
Int main (INT argc, char * argv []) {cexample theobjone; theobjone. init (40); cexample theobjthree; theobjthree. init (60); // now an object Value assignment operation is required. The original content of the assigned object is cleared and filled with the content of the right object. Theobjthree = theobjone; return 0 ;}
"=" Is also used, but it is different from the example in "1.". In the example of "1.", "=" indicates initialization in the object declaration statement. More often, such initialization can also be represented by parentheses.
For example, cexample theobjone (theobjtwo );
In this example, "=" indicates the value assignment operation. Copy the content of theobjone to theobjthree, which involves discarding the original content of theobjthree and copying new content.
However, the default operation of "=" only copies the value of the member variable. Old values are naturally discarded.
Because the object contains pointers, it will cause adverse consequences: the pointer value is discarded, but the content pointed to by the pointer is not released. The pointer value is copied, but the content indicated by the pointer is not copied.
Therefore, in addition to providing a copy constructor, classes that contain dynamically assigned members should also consider overloading the "=" value assignment operator symbol.
Class Definition changed:
Class cexample {... cexample (const cexample &); // copy the constructor cexample & operator = (const cexample &); // overload the value assignment operator ...};
// The Value assignment operator overload cexample & cexample: Operator = (const cexample & rightsides) {nsize = rightsides. nsize; // copy the regular member char * temp = new char [nsize]; // copy the content memcpy (temp, rightsides. pbuffer, nsize * sizeof (char); Delete [] pbuffer; // Delete the content pointed to by the original pointer (put the delete operation behind it to avoid the special case of X = x, content loss) pbuffer = temp; // creates a new point to return * This}
3. Copy the code that uses the value assignment operator to overload the constructor.
Cexample: cexample (const cexample & rightsides) {pbuffer = NULL; * This = rightsides // "= "}