Shallow copy and deep copy
In the Circle class, the example of the copy constructor explained in the previous section, the copy strategy is consistent with the system default strategy, that is, the members of the original object are copied to the corresponding members of the new object in sequence. In this case, why do we still Do you want to define it yourself? The reason is that simply initializing all situations in this simple way will inevitably lead to problems in different situations.
For example, in the Circle class just now, if a pointer member is added to the member variable and the memory needs to be dynamically allocated during initialization, there will be a huge security risk. The code is as follows:
/************************************//Des: C++ tutorial supporting program//Author :Huang//CopyRight:www.dotcpp.com//Date:2017/8/26****************************** ********/#include<iostream>#include<Cstring>usingnamespacestd;#definePI3.1415classCircle{private:doubleR;char*str;public:Circle(doubleR,char*str);~Circle(); doublearea();doublegirth();};Circle::~Circle(){delete[]str;}Circle::Circle(doubleR,char*str){cout<<Constructor<<endl;this->R=R ;this->str=newchar[strlen(str)+1];strcpy(this->str,str);cout<<this->R<<<<this->str<<endl;}doubleCircle::area (){returnPI*R*R;}doubleCircle::girth(){return2*PI*R;}intmain(){CircleA(5,NO.1Oldclass);CircleB(A);return0;}
To verify, in the Circle class, we added a pointer member and initialized it in the constructor without a custom copy constructor. Then in the main function, the sentence Circle B(A); assigns the A object to the B object, and calls the default generated copy constructor. After running, the program reports an error as shown below:
The actual reason is that the default copy constructor only performs data assignment and cannot open up memory space for pointers, which is equivalent to the code:
This->str=str;
So essentially, two pointers point to a piece of heap space. It has gone against our original intention. Then at the end of the program, when the two objects are recycled, their own destructors will be called to release this memory space. Since the two objects need to be called twice, that is, deleted twice, an error will occur!
Therefore, when there is a pointer type in the class, relying on the default copy constructor method can no longer meet our needs. A specific copy constructor must be defined, which can not only copy data, but also allocate memory space for members. , to achieve real copy, also called deep copy, this is the deep copy constructor .
Deep copy constructor implementation:
#include<iostream>#include<Cstring>usingnamespacestd;#definePI3.1415classCircle{private:doubleR;char*str;public:Circle(doubleR,char*str);Circle(Circle&A);~Circle();doublerea(); doublegirth();};Circle::~Circle(){delete[]str;cout<<CallDestructor<<endl;}Circle::Circle(Circle&A){cout<<CopyConstructor<<endl;this->R=AR ;this->str=newchar[strlen(A.str)+1];strcpy(this->str,A.str);}Circle::Circle(doubleR,char*str){cout<<Constructor<<endl ;this->R=R;this->str=newchar[strlen(str)+1];strcpy(this->str,str);}doubleCircle::area(){returnPI*R*R;}doubleCircle: :girth(){return2*PI*R;}intmain(){CircleA(5,NO.1Oldclass);CircleB(A);return0;}
The implementation principle is similar to the constructor with parameters. Sufficient memory space is opened before assignment to truly complete the complete copy. This is the so-called "deep copy". Please understand and try it on the computer!