String類 (淺拷貝 深拷貝 寫時拷貝)

2021-08-08 16:46:54 字數 3132 閱讀 9002

淺拷貝是指當物件的字段值被拷貝時,字段引用的物件不會被拷貝。例如,如果乙個物件有乙個指向字串的字段,並且我們對該物件做了乙個淺拷貝,那麼兩個物件將引用同乙個字串。

存在問題:

如果源程式中沒有顯示定義拷貝建構函式,在進行物件的拷貝時,將呼叫系統預設的拷貝建構函式,這就使得兩個物件指向了同一資源,而析構函式又在物件生命週期結束後可以釋放空間,勢必會兩次返還空間,編譯器就會報錯。

這時就需要用到深拷貝了。

深拷貝的兩種版本:

#define  _crt_secure_no_warnings 1  

#include

using

namespace

std;

//#if 0

class string

else

}//簡潔版

拷貝建構函式 1

//string(const string &s)

// :_pstr(new char[strlen(s._pstr) + 1])

//拷貝建構函式 2

//string(const string &s)

// :_pstr(null)

////普通版

string(const string &s)

:_pstr(new

char[strlen(s._pstr) + 1])

//賦值運算子過載

/* //由於ptemp在棧上,出了函式將銷毀,故錯誤

string &operator=(const string &s)//賦值運算子過載

return *this;}*/

//賦值運算子過載 1

/* string &operator=(const string &s)

//return *this;

if (this != &s)

return *this;}*/

//賦值運算子過載 2

string& operator=(const string& pstr)

return *this;

}~string() //析構函式

}friend ostream& operator

<

private:

char *_pstr;

};//輸出流過載

1、開闢兩個空間的計數,**如下:

#include

using

namespace

std;

class string

else

}string(const string &s)//拷貝建構函式

:_pstr(s._pstr)

, _pcount(s._pcount)

//賦值運算子過載

string & operator = (const string & s)

_pstr = s._pstr;

_pcount = s._pcount;

++*_pcount;}}

~string()//呼叫析構函式時 先--_pcount,判斷是否為0

}friend ostream& operator

<

private:

char * _pstr;

int * _pcount;

};ostream& operator

<

void funtest()

int main()

執行結果:

2、乙個空間的計數,**如下:

執行結果:

淺拷貝,深拷貝和寫時拷貝(string類)

淺拷貝 淺拷貝 編譯器只是直接將指標的值拷貝過來,結果多個物件共用了一塊記憶體,當乙個物件呼叫了析構函式將這塊記憶體釋放掉之後,另一些物件不知道這塊空間已經還給了系統,再次呼叫析構函式進行釋放時發現已經釋放了,就會造成程式崩潰。所以,在類的成員中有指標型別的成員變數的時候,必須對其寫出顯式的拷貝建構...

淺拷貝,深拷貝,寫時拷貝

淺拷貝 拷貝構造時複製指標僅僅是對指標的值拷貝,而不開闢新的空間這樣就會造成在析構的時候。會對同一塊記憶體釋放兩次。深拷貝 拷貝構造時會開闢新的記憶體,並把記憶體中的值進行拷貝 寫時拷貝 就是當你在讀取一片空間時,系統並不會為你開闢乙個一模一樣的空間給你 只有在當你真正修改的時候,才會開闢一片空間給...

深拷貝 淺拷貝 寫時拷貝

在拷貝構造的時候,直接將原內容的位址交給要拷貝的類,兩個類共同指向一塊記憶體。缺陷 1 一旦對str2進行操作,str1的內容也會改變 2 析構時先析構str2,再析構str1,但是由於str1,str2指向同一塊記憶體空間,因此會導致對一塊記憶體進行兩次析構而出現錯誤 通過開闢和源空間大小相同的記...