Write-time Copy reference counter model

Source: Internet
Author: User

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_ ()   &GT;&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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.