小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

深拷貝與淺拷貝到底是什么

 C語(yǔ)言與CPP編程 2021-12-15

復(fù)制構(gòu)造函數(shù)也叫拷貝構(gòu)造函數(shù);
淺復(fù)制也叫淺拷貝或位拷貝;
深復(fù)制也叫深拷貝;
淺拷貝和深拷貝
拷貝就是復(fù)制,創(chuàng)建副本。假設(shè)有對(duì)象A,A有屬性t1,t2。那么,我通過(guò)拷貝A,得到B,B應(yīng)該也有屬性t1,t2,且A、B兩個(gè)對(duì)象的每個(gè)屬性,都應(yīng)該是相同的。
對(duì)于基本類型的屬性t1,拷貝是沒(méi)有疑義的。簡(jiǎn)單將值復(fù)制一份,就達(dá)到了拷貝的效果。而對(duì)于引用類型的屬性t2來(lái)說(shuō),拷貝就有了兩層含義。
第一層是,我只是將t2引用的地址復(fù)制一份給B的t2,確實(shí)達(dá)到了屬性相同的效果,可以理解為實(shí)現(xiàn)了拷貝,但是事實(shí)上,兩個(gè)對(duì)象中的屬性t2對(duì)應(yīng)的是同一個(gè)對(duì)象。在B對(duì)象上對(duì)t2所指向的對(duì)象進(jìn)行操作,就會(huì)影響到A對(duì)象中的t2的值。
第二層是,我將A的t2所指向的對(duì)象,假設(shè)為o1,完整復(fù)制一份,假設(shè)為o2,將新的o2的地址給B的t2。也達(dá)到了復(fù)制的效果,且對(duì)B的t2所指向的o2進(jìn)行操作,不會(huì)影響到A的t2所指向的o1。
拷貝的兩層含義,對(duì)應(yīng)了淺拷貝和深拷貝的概念,做了第一層,就是淺拷貝,做到第二層,就是深拷貝。

基于以上內(nèi)容,很容易可以想到,淺拷貝比深拷貝要更快,但是,從拷貝的意義上來(lái)看,淺拷貝相較于深拷貝,要欠缺一點(diǎn)。

實(shí)例如下:

#include <iostream>using namespace std;//20200430 公眾號(hào):C語(yǔ)言與CPP編程
class CopyDemo{public: CopyDemo(int pa,char *cstr) //構(gòu)造函數(shù),兩個(gè)參數(shù) { this->a = pa; this->str = new char[1024]; //指針數(shù)組,動(dòng)態(tài)的用new在堆上分配存儲(chǔ)空間 strcpy(this->str,cstr); //拷貝過(guò)來(lái) }
//沒(méi)寫,C++會(huì)自動(dòng)幫忙寫一個(gè)復(fù)制構(gòu)造函數(shù),淺拷貝只復(fù)制指針,如下注釋部分 //CopyDemo(CopyDemo& obj) //{ // this->a = obj.a; // this->str = obj.str; //這里是淺復(fù)制會(huì)出問(wèn)題,要深復(fù)制 //}
CopyDemo(CopyDemo& obj) //一般數(shù)據(jù)成員有指針要自己寫復(fù)制構(gòu)造函數(shù),如下 { this->a = obj.a; // this->str = obj.str; //這里是淺復(fù)制會(huì)出問(wèn)題,要深復(fù)制 this->str = new char[1024];//應(yīng)該這樣寫 if(str != 0) strcpy(this->str,obj.str); //如果成功,把內(nèi)容復(fù)制過(guò)來(lái) }
~CopyDemo() //析構(gòu)函數(shù) { delete str; }
public: int a; //定義一個(gè)整型的數(shù)據(jù)成員 char *str; //字符串指針};
int main(){ CopyDemo A(100,"hello!!!");
CopyDemo B = A; //復(fù)制構(gòu)造函數(shù),把A的10和hello!!!復(fù)制給B cout <<"A:"<< A.a << "," <<A.str << endl; //輸出A:100,hello!!! cout <<"B:"<< B.a << "," <<B.str << endl; //輸出B:100,hello!!!
//修改后,發(fā)現(xiàn)A,B都被改變,原因就是淺復(fù)制,A,B指針指向同一地方,修改后都改變 B.a = 80; B.str[0] = 'k';
cout <<"A:"<< A.a << "," <<A.str << endl; //輸出A:100,kello!!! cout <<"B:"<< B.a << "," <<B.str << endl; //輸出B:80,kello!!!
return 0;}

根據(jù)上面實(shí)例可以看到,淺復(fù)制僅復(fù)制對(duì)象本身(其中包括是指針的成員),這樣不同被復(fù)制對(duì)象的成員中的對(duì)應(yīng)非空指針會(huì)指向同一對(duì)象,被成員指針引用的對(duì)象成為共享的,無(wú)法直接通過(guò)指針成員安全地刪除(因?yàn)槿糁苯觿h除,另外對(duì)象中的指針就會(huì)無(wú)效,形成所謂的野指針,而訪問(wèn)無(wú)效指針是危險(xiǎn)的;除非這些指針有引用計(jì)數(shù)或者其它手段確保被指對(duì)象的所有權(quán));而深復(fù)制在淺復(fù)制的基礎(chǔ)上,連同指針指向的對(duì)象也一起復(fù)制,代價(jià)比較高,但是相對(duì)容易管理。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多