1、深淺拷貝的使用時(shí)機(jī):
創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元金湖做網(wǎng)站,已為上家服務(wù),為金湖各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220淺拷貝:對(duì)只讀數(shù)據(jù)共用一份空間,且只釋放一次空間;
深拷貝:數(shù)據(jù)的修改,的不同空間;
2、引用計(jì)數(shù)器模型
使用變量use_count,來(lái)記載初始化對(duì)象個(gè)數(shù);
static模型(此處只用淺拷貝與淺賦值)
#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++; //每新創(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<<s1.GetString()<<endl; String s2; s2 = s1; //淺賦值,調(diào)用默認(rèn)的; cout<<s2.GetString()<<endl; String s3("xyz"); //創(chuàng)建t3對(duì)象,要出問(wèn)題了;(對(duì)其就只創(chuàng)建出來(lái),不在進(jìn)行賦值語(yǔ)句等操作);此時(shí)的情況是:已經(jīng)有兩個(gè)對(duì)象,其成員data指向同一空間,此時(shí)又有一個(gè)data指向另一個(gè)空 //間,但是use_count為0才釋放空間,只釋放一份,所以肯定有內(nèi)存泄漏?。?! return 0; }
上面的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í),釋放空間,
3、寫時(shí)拷貝
淺拷貝與深拷貝聯(lián)合使用,看實(shí)際需求對(duì)其編寫,此時(shí)我希望,對(duì)數(shù)據(jù)讀時(shí)共用一份數(shù)據(jù),需要修改時(shí),在單獨(dú)開(kāi)辟空間進(jìn)行修改,在進(jìn)行改寫,并且對(duì)象(初始化)應(yīng)該有自己的data和use_count,賦值語(yǔ)句時(shí)共用一份就行,此時(shí)就需要句柄了,這就是寫時(shí)拷貝;
具體完整代碼如下:
#include<iostream> #include<malloc.h> #include<string.h> 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<<rep->data<<endl; } void toupper(){ //這個(gè)函數(shù)提供的意義:對(duì)其要改的對(duì)象重新申請(qǐng)空間,進(jìn)行改寫,使相互之間不影響。 if(rep->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 = "<<s1.use_count()<<endl; s2.print(); cout<<"s2 count = "<<s2.use_count()<<endl; s3.print(); cout<<"s3 count = "<<s3.use_count()<<endl; return 0; }
以上的代碼就可以達(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)一份即可。
分析如下:
關(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í)拷貝的粗淺理解。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
標(biāo)題名稱:寫時(shí)拷貝引用計(jì)數(shù)器模型-創(chuàng)新互聯(lián)
地址分享:http://www.rwnh.cn/article46/hsehg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、品牌網(wǎng)站設(shè)計(jì)、商城網(wǎng)站、用戶體驗(yàn)、網(wǎng)站策劃、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容