真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

寫時(shí)拷貝引用計(jì)數(shù)器模型

1、深淺拷貝的使用時(shí)機(jī):

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)敘永免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了成百上千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

  淺拷貝:對(duì)只讀數(shù)據(jù)共用一份空間,且只釋放一次空間;

  深拷貝:數(shù)據(jù)的修改,的不同空間;

2、引用計(jì)數(shù)器模型

  使用變量use_count,來(lái)記載初始化對(duì)象個(gè)數(shù);

  static模型(此處只用淺拷貝與淺賦值)

#include
#include
#include
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++;     //每新創(chuàng)建一個(gè)對(duì)象,對(duì)引用計(jì)數(shù)器++;
    }
    String(const String &s){
        data = s.data;
        use_count++;      //創(chuàng)建出新的對(duì)象,use_count++;
    }
 //此處先不寫賦值語(yǔ)句
    ~String(){
        if(--use_count == 0){  //當(dāng)引用計(jì)數(shù)器減為0時(shí),就是每次行析構(gòu)對(duì)象時(shí),都對(duì)它減一次,直到為0才釋放空間,
            delete []data;
            data = NULL;
        }
    }
public:
    char* GetString()const{
        return data;
    }
private:
    char *data;
    static int use_count;   //此處use_count只有一份,負(fù)責(zé)記載創(chuàng)建了多少個(gè)對(duì)象;
};

int String::use_count = 0;  //C++中的靜態(tài)變量全局只有一份,可以再類外進(jìn)行初始化;

int main(void)
{
    String s1("hello");
    cout<

  上面的static淺拷貝其實(shí)存在很大的問(wèn)題,當(dāng)t3對(duì)象創(chuàng)建時(shí),use_count會(huì)加1;

  當(dāng)調(diào)用析構(gòu)函數(shù)時(shí),每次減1,為0時(shí),釋放空間,

寫時(shí)拷貝 引用計(jì)數(shù)器模型

3、寫時(shí)拷貝

  淺拷貝與深拷貝聯(lián)合使用,看實(shí)際需求對(duì)其編寫,此時(shí)我希望,對(duì)數(shù)據(jù)讀時(shí)共用一份數(shù)據(jù),需要修改時(shí),在單獨(dú)開辟空間進(jìn)行修改,在進(jìn)行改寫,并且對(duì)象(初始化)應(yīng)該有自己的data和use_count,賦值語(yǔ)句時(shí)共用一份就行,此時(shí)就需要句柄了,這就是寫時(shí)拷貝;

  具體完整代碼如下:

#include
#include
#include
using namespace std;
class String;
class String_rep{        // 這個(gè)類是封裝在內(nèi)部供我們程序員自己使用的。
    friend class String;  //友元類,可以訪問(wèn)私有數(shù)據(jù)。
public:
    String_rep(const char *str = ""):use_count(0){  //構(gòu)造函數(shù)的初始化
        if(str == NULL){
            data = new char[1];
            data[0] = 0;
        }else{
            data = new char[strlen(str)+1];
            strcpy(data,str);
        }
    }
    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(){   //這個(gè)函數(shù)至關(guān)重要,寫了一個(gè)釋放空間的函數(shù),要在其后賦值語(yǔ)句中使用;
        if(--use_count == 0)
            delete this;
    }
    int use_count_()const{
        return use_count;
    }
public:
    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 = s.rep;
            rep->increment();
        }
        return *this;
    }
    ~String(){
        rep->decrement();
    }
public:
    int use_count()const{
        return rep->use_count_();
    }
    void print()const{
        cout<data<use_count_() > 1){ //對(duì)象個(gè)數(shù)大于1才進(jìn)行拷貝出來(lái)重新寫,只有一個(gè)就直接在其上進(jìn)行修改。
            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; // 句柄
};
int main(){
    String s1("hello");
    String s2 = s1;
    String s3("xyz");
    s3 = s2;
    s1.toupper();
    s1.print();
    cout<<"s1 count = "<

以上的代碼就可以達(dá)到目的,每次創(chuàng)建對(duì)象都有自己的data和use_count(調(diào)用構(gòu)造函數(shù)),在賦值語(yǔ)句時(shí)先釋放原有空間,在進(jìn)行淺拷貝,構(gòu)造函數(shù)時(shí)也是淺拷貝,對(duì)其進(jìn)行了各自空間的管理與釋放,并且在修改數(shù)據(jù)時(shí)拷貝出來(lái)一份即可。

寫時(shí)拷貝 引用計(jì)數(shù)器模型

分析如下:

寫時(shí)拷貝 引用計(jì)數(shù)器模型

關(guān)于以上還有個(gè)問(wèn)題:就是:

void decrement(){   
  if(--use_count == 0)
   delete this;
}

為什么不在String類的析構(gòu)函數(shù)中寫delete呢?

原因:析構(gòu)函數(shù)只有在對(duì)象釋放是才調(diào)用,而在此時(shí),通過(guò)賦值語(yǔ)句要釋放空間,析構(gòu)函數(shù)此時(shí)就不能及時(shí)釋放原有空間,會(huì)造成內(nèi)存泄漏,所以寫一個(gè)釋放空間的函數(shù),內(nèi)部有delete,會(huì)先調(diào)用析構(gòu)函數(shù),達(dá)到了及時(shí)釋放空間的目的!

以上只是對(duì)寫時(shí)拷貝的粗淺理解。


本文標(biāo)題:寫時(shí)拷貝引用計(jì)數(shù)器模型
網(wǎng)站URL:http://weahome.cn/article/jgesod.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部