綜述:
當兩個物件要共享乙份資料時,如果資料不改變,不進行資料的複製,通過淺拷貝就可以資料的共享;而當物件需要改變資料時,則做深貝。
程式在處理共享物件時,會使用淺拷貝和深拷貝這兩種方法複製物件。
(1)深拷貝:即就是生成物件的乙個完整的複製品;
(2)淺拷貝:只是乙個引用複製(比如僅僅複製指向共享資料的指標)。
這樣看來,深拷貝其實是代價比較高的,要占用更多的記憶體和cpu資源;而淺拷貝的效率要更好些,因為它僅僅需要設定乙個指向共享資料塊的指標以及修改引用的計數器。
(3)隱式共享:也叫做回寫複製(copy on write)。
隱式共享可以降低對記憶體和cpu資源的使用,提高程式的執行效率。使用隱式共享能使得在函式中(eg. 引數、返回值)使用值傳遞更有效率。 qstring採用隱式共享技術,將深拷貝和淺拷貝很好地結合了起來。
舉例說明飲食共享是如何工作的:
qstring str1 =
"ubuntu"
;qstring str2 = str1;
//str2 =
"ubuntu"
str2[2]
="m";/
/str2 =
"ubmntu"
,str1 =
"ubuntu"
str2[0]
="o";/
/str2 =
"obmntu"
,str1 =
"ubuntu"
str1 = str2;
//str1 =
"obmntu",
line1: 初始化乙個內容為"ubuntu"的字串;
line2: 將字串物件str1賦值給另外乙個字串str2(由qstring的拷貝建構函式完成str2的初始化)。
在對str2賦值的時候,會發生一次淺拷貝,導致兩個qstring物件都會指向同乙個資料結構。該資料結構除了儲存字串「ubuntu」之外,還儲存乙個引用計數器,用來記錄字串資料的引用次數。此處,str1和str2都指向同一資料結構,所以此時引用計數器的值為2.
line3: 對str2做修改,將會導致一次深拷貝,使得物件str2指向乙個新的、不同於str1所指的資料結構(該資料結構中引用計數器值為1,只有str2是指向該結構的),同時修改原來的、str1所指向的資料結構,設定它的引用計數器值為1(此時只有str1物件指向該結構);並在這個str2所指向的、新的資料結構上完成資料的修改。引用計數為1就意味著該資料沒有被共享。
line4: 進一步對str2做修改,不過不會引起任何形式的拷貝,因為str2所指向的資料結構沒有被共享。
line5: 將str2賦給str1.此時,str1修改它指向的資料結構的引用計數器的值位0,表示沒有qstring類的物件再使用這個資料結構了;因此str1指向的資料結構將會從從記憶體中釋放掉;這一步操作的結構是qstring物件str1和str2都指向了字串為「obmntu」的資料結構,該結構的引用計數為2.
qt中支援引用計數的類有很多(qbytearray, qbrush, qdir, qbitmap... ...).
from:
淺拷貝 深拷貝
copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...
深拷貝 淺拷貝
c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...
淺拷貝 深拷貝
retain是建立乙個指標,引用物件計數加1。copy屬性表示兩個物件內容相同,新的物件retain為1 與舊有物件的引用計數無關,舊有物件沒有變化。copy減少物件對上下文的依賴。retain屬性表示兩個物件位址相同 建立乙個指標,指標拷貝 內容當然相同,這個物件的retain值 1也就是說,re...