淺拷貝是指當物件的字段值被拷貝時,字段引用的物件不會被拷貝。例如,如果乙個物件有乙個指向字串的字段,並且我們對該物件做了乙個淺拷貝,那麼兩個物件將引用同乙個字串。
存在問題:
如果源程式中沒有顯示定義拷貝建構函式,在進行物件的拷貝時,將呼叫系統預設的拷貝建構函式,這就使得兩個物件指向了同一資源,而析構函式又在物件生命週期結束後可以釋放空間,勢必會兩次返還空間,編譯器就會報錯。
這時就需要用到深拷貝了。
深拷貝的兩種版本:
#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指向同一塊記憶體空間,因此會導致對一塊記憶體進行兩次析構而出現錯誤 通過開闢和源空間大小相同的記...