First, the introduction of the copy constructor
In general data types, we often use a variable to initialize another variable, for example:
int Ten ; int B = A;
Using the A variable to initialize the B variable, similarly, the object created for the class can use one object to initialize another object in this way. For example, in the point class described in the previous article, you use one object to initialize another object:
-Point.h//Point.h#include <iostream>classPoint { Public: Point (intx =0,inty =0): XPos (x), YPos (y) {}voidPrintpoint () {std::cout<<"XPos ="<< XPos <<Std::endl; Std::cout<<"YPOs ="<< YPos <<Std::endl; } Private: intXPos; intYPos; };
" Point.h " int Main () {Point M (ten); = M; // initializing an object with object M N n.printpoint (); return 0 ; }
Results of the compilation run:
0(0x0) 0.462 s continue.
The code above uses the point class to create an object M, initialize xpos, ypos 10 and 20, at point n = m; This line creates an object N and has initialized M to initialize it, so when object n is called Printpoi The output of NT is the same as the xpos of M and the ypos value.
Statement point N = M; Can also be written in the form of Point N (M); Executing the sentence is equivalent to assigning the value of each data member in M to the member data corresponding to the object N. Of course, this is only a superficial phenomenon, in fact, the system calls a copy constructor to complete this part of the action, when the class does not explicitly define the copy constructor, the compiler will default to generate a default copy constructor, also known as the copy constructor, the prototype of the function is as follows:
Const Point &);
The copy constructor can also be considered as a normal constructor, except that the formal parameters of the function are different, and the parameters of the copy constructor are reference types of the objects of this class.
Second, the default copy constructor is insufficient
Although there is a default copy constructor to solve the initialization problem between the general object and the object, in some cases we must manually explicitly define the copy constructor, for example:
#include <iostream>#include<cstring>using namespacestd; classBook { Public: Book (Const Char*name) {BookName=New Char[Strlen (name) +1];//use new to request strlen (name) +1 size spacestrcpy (bookname, name); } ~book () {Delete[]bookname; }//free space for the request voidShowName () {cout<<"Book name:"<< BookName <<Endl;} Private: Char*BookName; }; intMain () {Book CPP ("C + + Primer"); Book T (CPP); //initializing an object with CPP TCpp.showname (); CPP.~book ();//manually release the space that the object CPP applies toT.showname (); return 0; }
Results of the compilation run:
Book name:c++ Primer book name: 0 (0x0) 0.281 s continue.
After using the CPP object to initialize the T object, the BookName property of the T object is theoretically "C + + Primer", but it is normal for the output of the BookName property of the CPP object, as shown in the previous idea, and the T object's BookName output has a problem, the correct case should also be "C + + Primer", but this time the output is blank.
This is one of the disadvantages of the constructor, which is caused by Cpp.~book (); this line, restores the implementation of the default copy constructor:
Const Book &obj) { = obj.bookname; }
As you can see, in fact, when you initialize a T object with a CPP object, the default copy constructor simplyCPPObject thatBookNameAssign a value toTObject thatBookNameIn other words, that is, simply assigning the bookname of the CPP object to the bookname of T, so that the bookname of the BookName and CPP objects of the T object is pointing to the same deposit cell, when the CPP object calls the destructor function, the memory unit that the bookname of the CPP points to is released, because the T object BookName to the same memory as the bookname of the CPP object, so the memory that the T object's bookname points to becomes an unusable illegal content ( Because it has been released), the output will inevitably result in an output error if the directed memory is released.
In general, it is best to manually explicitly define a copy constructor to avoid this problem when the class contains a pointer-type data member and needs to use dynamic memory.
Third, explicitly define the copy constructor
The steps to explicitly define a copy constructor are simple, as long as you remember that the parameters of the function are references to members of this class, although they can also be implemented by pointers, it is not recommended to do so in a way that pointers are more dangerous than references. Explicitly defining the copy constructor resolves the problem in the previous example:
#include <iostream>#include<cstring>using namespacestd; classBook { Public: Book (Const Char*name) {BookName=New Char[Strlen (name) +1]; strcpy (bookname, name); } Book (ConstBook &obj)//To explicitly define a copy constructor{bookname=New Char[Strlen (Obj.bookname) +1];//request a new space again when you call the copy constructorstrcpy (BookName, obj.bookname); } ~book () {Delete[]bookname; }//free space for the request voidShowName () {cout<<"Book name:"<< BookName <<Endl;} Private: Char*BookName; }; intMain () {Book CPP ("C + + Primer"); Book T= CPP;//initializing an object with CPP TCpp.showname (); CPP.~book ();//manually release the space that the object CPP applies toT.showname (); return 0; }
Results of the compilation run:
Book name:c++ Primer book name:c+ Primer 0 (0x0) 0.281 s continue.
In this example, we explicitly define a copy constructor in place of the default copy constructor, in the function body of the copy constructor, instead of assigning the address of the source object to the initialized object directly, and then copying the properties of the source object when you request a memory independently, then the CPP object's The bookname of the bookname with the T object is to point to two different memory units, so that the object T initialized after the source object CPP is destroyed will no longer be affected.
Copy constructors, C + +