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