C string的深拷貝與淺拷貝

2021-07-31 08:42:24 字數 1950 閱讀 5176

在c++中,基本所有的類都要考慮深拷貝,淺拷貝與寫時拷貝,根據不同的定義,選擇適合自己的拷貝方式。時間類就可以用淺拷貝,而二叉樹,string類就需要深拷貝。

string類在vs編譯器下使用的深拷貝,在linux下使用的淺拷貝。

為什麼會存在深淺拷貝的問題呢?

string的淺拷貝是讓兩個不同的指標指向同一塊空間,而這在析構的時候會出現將一塊空間釋放兩次,程式會崩潰,因此我們才需要進行深拷貝,即第二個指標開闢和第乙個指標一樣大小空間,然後將內容複製過去。

深拷貝:

class string

else

//strcpy(str,pstr);

//memcpy(str,pstr,strlen(pstr)+1);淺複製

} }//拷貝建構函式

string(const string& pstr)

:str(new char[strlen(pstr.str)+1])

//strcpy(str,pstr.str);

//memcpy(str,pstr.str,strlen(pstr.str)+1);

} //賦值運算子過載

string& operator = (const string & pstr)

//strcpy(str,pstr.str);

//memcpy(str,pstr.str,strlen(pstr.str)+1);

return *this;

} /*現**法: 根據拷貝建構函式讓系統自己開闢空間

拷貝建構函式

string(const string& pstr)

:str=null; 必須置為空,要不然訪問位址非法化

賦值運算子過載

string& operator = (const string& pstr )

*/ //析構函式

~string()

private:

char* str;

};int main()

淺拷貝,當我們需要改變新的空間的內容的時候,才會重新開闢空間呢?

1)判斷空間使用的次數來選擇析構,增加乙個類成員 count,但是這樣造成的後果是每乙個成員都有乙個不同的count 在析構的時候就很混亂還是會出錯

2)然後呢我們會想到使用靜態成員的辦法,因為此時 static int count 是放在靜態區,它是所有物件共享的,不會為每個物件單獨生成乙個count,可是當我們有多個不同的成員共同管理一塊空間,而此時我們又用建構函式建立乙個物件時候,count又會變為1,所以這種方法還是不行 。

3)使用引用計數,把引用計數放在字串的前四個位元組裡,每個建立出來的物件都有不同的引用計數

class string

else

//strcpy(str,pstr);

//memcpy(str,pstr,strlen(pstr)+1);淺複製

} }//拷貝建構函式

string(const string& pstr)

//賦值運算子過載

string& operator = (const string & pstr)

void destroy()

else

--*count;

}//析構函式

~string()

private:

char* str;

int * count;

};

寫時拷貝:

在淺拷貝中,假設有多個名稱引用了同乙個字串,當其中乙個需要修改字串時,這就會導致引用的值發生改變,這明顯不是我們所期望的,所以出現了寫時拷貝,(可能會修改字串的時候使用深拷貝將其與大部隊分離,這樣就保護了其他引用成員)

則我們只需要過載 就可以實現

const string& operatorconst 

C String類的實現(淺拷貝 深拷貝)

首先大家看下以下string類的實現是否有問題?class string str newchar strlen str 1 strcpy str,str string 測試 上述string類沒有顯式定義其拷貝建構函式與賦值運算子過載,此時編譯器會合成預設的,當用s1構造s2時,編譯器會呼叫預設的拷...

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝與深拷貝

淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...