1, the use of the time-depth copy:
Shallow copy: Share a space for read-only data and release only one space;
Deep copy: The change of data, the different space;
2. Reference counter Model
Use variable Use_count to record the number of initialized objects;
(1), static model (only shallow copy and shallow assignment here)
#include <iostream> #include <string.h> #include <malloc.h>using namespace std;class string{public: string (const char *str = "") { if (str == null) { data = new char; data[0] = 0; }else{ data = new char[strlen (str) + 1]; strcpy (DATA,STR); } use_count++; //each newly created object, the reference counter ++; } string (const String &s) { data = s.data; use_count++; //creates a new object, use_count++; } // The assignment statement ~string () { if (--use_count) is not written here first == 0) { //When the reference counter is reduced to 0 o'clock, that is, every time the row is refactored, it is reduced one time until it is 0 to free the space, delete []data; data = NULL; } }public: char* getstring () const{ return data; }private: char *data; static int use_count; //here Use_count only one, responsible for documenting the number of objects created;};int string: : USE_COUNT&NBSP;=&NBSP;0;&NBSP;&NBThere is only one copy of the static variable in the sp;//c++, which can be initialized outside of the class; Int main (void) { string s1 ("Hello"); cout<<s1. GetString () <<endl; String s2; s2 = s1; //shallow assignment, call default; cout<<s2. GetString () <<endl; string s3 ("xyz") //create T3 object, it's going to be a problem; Not in an assignment statement, etc.); The situation is that there are already two objects whose member data points to the same space, and another data point to another null //, but the Use_count is 0 to free space, Only release one copy, so there must be a memory leak!!! return 0;}
The above static shallow copy actually has the very big question, when T3 object creation, the Use_count will add 1;
When the destructor is called, it is reduced by 1 at a time, 0 o'clock, freeing the space,
650) this.width=650; "Src=" Http://s1.51cto.com/wyfs02/M02/84/76/wKiom1eRSdWhZPOZAAA4D_AGtwo451.png-wh_500x0-wm_3 -wmp_4-s_3519635876.png "title=" Qq20160722061630.png "alt=" Wkiom1ersdwhzpozaaa4d_agtwo451.png-wh_50 "/>
3. Copy when writing
Shallow copy and deep copy joint use, see the actual need to write to it, at this time I hope that the data read when a common data, need to modify, in a separate space to modify, in the rewriting, and the object (initialization) should have its own data and use_count, the assignment of the statement when a share on the line, At this point the handle is needed, this is the copy when writing;
The exact complete code is as follows:
#include <iostream> #include <malloc.h> #include <string.h>using namespace std;class String;class String_rep{ // This class is encapsulated internally for our programmers to use. friend class string; //a friend class that can access private data. Public: string_rep (const char *str = ""): Use_count (0) { / /constructor Initialization if (Str == null) { data = new char[1]; data[0] = 0; }else{ data = new char[strlen (str) +1]; strcpy (data, STR); &nbsP;} } string_rep (Const string_rep &rep); string_rep& operator= (const string_rep &rep); ~ String_rep () { delete []data; data = NULL; }public: void Increment () { use_count++; } void decrement () { //This function is important, write a function to free space, to use in subsequent assignment statements; if (--use_count == 0) delete this; } int use_count_ () const{ return use_count; }public: &nBsp; char *getdata () const{ return data; }private: char *data; int use_count;}; Class string{public: string (const char *str = ""): Rep (new string_rep (str)) { rep->increment (); } string (const string &s) { rep = s.rep; rep->increment (); } string& operator= (const string &s) { if (this != &s) { rep->decrement (); rep =&nBsp;s.rep; rep->increment (); } return *this; } ~string () { Rep->decrement (); }public: int use_count () const{ return rep->use_count_ (); } void print () const{ cout<<rep-> Data<<endl; } void toupper () { //the meaning of this function: re-apply the space to the object it wants to change, and rewrite it so that it doesn't affect each other. if (Rep->use_count_ () >&NBSP;1) {The number of //objects is greater than 1 to be copied and re-written, only one is modified directly on it. string_rep *new_rep = new string_rep (rep-> data); this->rep->decrement (); rep = new_rep; rep->increment (); } char *pch = rep->data; while (*PCH) { *pch -= 32; pch++; } }private: String_rep *rep; // handle};int main () { string S1 ("Hello"); &nbSp STRING&NBSP;S2&NBSP;=&NBSP;S1;&NBSP;&NBSP;&NBSP;&NBSP;STRING&NBSP;S3 ("xyz"); s3 = s2; s1.toupper (); s1.print (); cout << "s1 count = " <<s1.use_count () <<endl; s2.print (); cout<< "s2 count = " <<s2.use_count () <<endl; s3.print (); cout<< "s3 count = " <<s3.use_ Count () <<endl; return 0;}
The above code can achieve the purpose, each creation of the object has its own data and Use_count (call constructor), in the assignment of the original space in the statement, the shallow copy, the constructor is also a shallow copy, the respective space for the management and release, and copy it when you modify the data.
650) this.width=650; "Src=" Http://s4.51cto.com/wyfs02/M01/84/84/wKiom1eSvX6SeskfAAAWwWMfN1I485.png-wh_500x0-wm_3 -wmp_4-s_2239716158.png "title=" Qq20160723084218.png "alt=" Wkiom1esvx6seskfaaawwwmfn1i485.png-wh_50 "/>
The analysis is as follows:
650) this.width=650; "Src=" Http://s3.51cto.com/wyfs02/M02/84/84/wKiom1eSwDzg87GTAAAvQIZybAw459.png-wh_500x0-wm_3 -wmp_4-s_666425464.png "title=" Qq20160723085355.png "alt=" Wkiom1eswdzg87gtaaavqizybaw459.png-wh_50 "/>
There is one more question about:
void Decrement () {if (--use_count = = 0) Delete this; }
Why not write Delete in the destructor of the string class?
Cause: destructors only in the object release is called, and at this time, through the assignment statement to free up space, destructors at this time can not release the original space, will cause memory leaks, so write a free space function, the internal delete, will first call the destructor, to achieve the purpose of free space in time!
The above is only a superficial understanding of the copy at the time of writing.
Write-time Copy reference counter model