C++的深淺拷貝和寫(xiě)時(shí)拷貝你了解嗎
1.淺拷貝
淺拷貝:對(duì)于有申請(qǐng)空間的對(duì)象的類(lèi)來(lái)說(shuō),是按照字節(jié)序依次拷貝過(guò)去的,并沒(méi)有另外申請(qǐng)一塊空間。因此,在調(diào)用析構(gòu)函數(shù)的時(shí)候會(huì)造成同一塊空間釋放兩次的情況,從而使程序崩潰。
如下實(shí)例:
class string
{
public:
string(const char* str)
{
//構(gòu)造string類(lèi)對(duì)象時(shí),如果傳遞nullptr指針
//認(rèn)為程序非法,此處斷言下
assert(str);
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
~string()
{
if (_str)
{
delete[] _str;
_str = nullptr;
}
}
private:
char* _str;
};
void test()
{
string s1("linmanman");
string s2(s1);
}
運(yùn)行看看,報(bào)錯(cuò)了

分析錯(cuò)因:


淺拷貝是指向同一塊空間的,這樣就會(huì)有倆個(gè)無(wú)法避免的問(wèn)題:
1.析構(gòu)倆次空間,程序崩潰
2.其中一個(gè)的值被修改了,會(huì)影響到另外一個(gè)的值。
深拷貝:給每個(gè)對(duì)象單獨(dú)分配資源,就是給待拷貝的對(duì)象另開(kāi)一片空間,再把原對(duì)象空間上的值拷貝過(guò)來(lái),這樣在調(diào)用析構(gòu)函數(shù)的時(shí)候就不會(huì)產(chǎn)生沖突。


2.深拷貝
傳統(tǒng)寫(xiě)法的string類(lèi)的深拷貝是自己開(kāi)空間,自己將拷貝的對(duì)象拷貝到待拷貝對(duì)象中。
string(const string& s)
: _str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
}
string& operator=(const string& s)
{
if(this != &s)
{
char* pStr = new char[strlen(s._str) + 1];
strcpy(pStr, s._str);
delete[] _str;
_str = pStr;
}
return *this;
}
現(xiàn)代寫(xiě)法的string類(lèi)的深拷貝堪稱是“移花接木”
string(const string& s)
:_str(nullptr)//必須置空,因?yàn)開(kāi)str開(kāi)始是個(gè)隨機(jī)數(shù),交換給tmp._str后,釋放會(huì)引起問(wèn)題
{
string tmp(s._str);//直接利用構(gòu)造函數(shù),給tmp對(duì)象開(kāi)辟了一塊空間
swap(tmp);
}
string& operator=(string s)
{
swap(s);//這個(gè)swap是咱們自己寫(xiě)的哦
return *this;
}
順帶提一嘴,各個(gè)編譯器深拷貝的底層實(shí)現(xiàn)略有差異(當(dāng)然邏輯是一樣的)
VS 2013下的深拷貝

g++下的深拷貝

3.引用計(jì)數(shù)+寫(xiě)時(shí)拷貝
寫(xiě)時(shí)拷貝就是一種拖延癥, 是在淺拷貝的基礎(chǔ)之上增加了引用計(jì)數(shù)的方式來(lái)實(shí)現(xiàn)的。
引用計(jì)數(shù):用來(lái)記錄資源使用者的個(gè)數(shù)。在構(gòu)造時(shí),將資源的計(jì)數(shù)給成1,每增加一個(gè)對(duì)象使用該資源,就給計(jì)數(shù)增加1,當(dāng)某個(gè)對(duì)象被銷(xiāo)毀時(shí),先給該計(jì)數(shù)減1,然后再檢查是否需要釋放資源,如果計(jì)數(shù)為1,說(shuō)明該對(duì)象時(shí)資源的最后一個(gè)使用者, 將該資源釋放;否則就不能釋放,因?yàn)檫€有其他對(duì)象在使用該資源。

總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++日期類(lèi)計(jì)算器的模擬實(shí)現(xiàn)舉例詳解
兩個(gè)日期之間相隔天數(shù)的計(jì)算網(wǎng)上有許多的軟件,這里主要介紹如何使用C/C++語(yǔ)言來(lái)完成這樣的功能,下面這篇文章主要給大家介紹了關(guān)于C++日期類(lèi)計(jì)算器的模擬實(shí)現(xiàn),需要的朋友可以參考下2023-04-04
C語(yǔ)言實(shí)現(xiàn)掃雷游戲(可以自動(dòng)展開(kāi))
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)掃雷游戲,可以自動(dòng)展開(kāi),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
Python擴(kuò)展C/C++庫(kù)的方法(C轉(zhuǎn)換為Python)
這篇文章主要介紹了Python擴(kuò)展C/C++庫(kù)的方法(C轉(zhuǎn)換為Python),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
C++ Cmake的構(gòu)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)詳解
這篇文章主要為大家詳細(xì)介紹了C++ Cmake的構(gòu)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03

