本文目錄一覽:
- 1、淺複製和深複製的區別?
- 2、編程裡面的深拷貝和淺拷貝各是什麼意思,怎麼理解這兩個?
- 3、什麼是深拷貝和淺拷貝
- 4、淺拷貝與深拷貝的區別
- 5、PHP對象的淺複製與深複製的實例詳解
- 6、深複製(Deep Copy)、淺複製(Shallow Copy)、copy、mutableCopy
淺複製和深複製的區別?
淺層複製:只複製指向對象的指針,而不複製引用對象本身。
深層複製:複製引用對象本身。
編程裡面的深拷貝和淺拷貝各是什麼意思,怎麼理解這兩個?
1、淺拷貝:默認的拷貝就是淺拷貝。 僅僅多了個指針指向原來的空間。
2、深拷貝:自己寫的拷貝,自己申請了動態內存空間,用了new 或 malloc 。不但多了指針,而且多了空間。
3、用深拷貝的話,最好用自己寫的析構,記得在裡面釋放內存,也可以用默認析構。
4.用淺拷貝(即默認隱藏的拷貝),最好用默認析構,若用自己寫的析構裡面 ,記得不要釋放內存,不然會造成重複釋放內存而報錯。
什麼是深拷貝和淺拷貝
淺拷貝就是指對象複製的時候只複製一層;深拷貝是指複製對象的所有層級。
深拷貝和淺拷貝,主要是對象發生複製的時候,根據複製的層級不同來區分的。很多人在這裡經常變量賦值發生混淆。對於JavaScript數組等複雜的數據類型來說,將其賦值給其它變量,其實只是複製了對象的地址給它,兩個變量指向的是同一個對象,因此普通的賦值既不是深拷貝也不是淺拷貝。
深拷貝和淺拷貝需要注意的地方就是可變元素的拷貝:
在淺拷貝時,拷貝出來的新對象的地址和原對象是不一樣的,但是新對象裡面的可變元素(如列表)的地址和原對象里的可變元素的地址是相同的,也就是說淺拷貝它拷貝的是淺層次的數據結構(不可變元素),對象里的可變元素作為深層次的數據結構並沒有被拷貝到新地址裡面去。
而是和原對象里的可變元素指向同一個地址,所以在新對象或原對象里對這個可變元素做修改時,兩個對象是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對於深拷貝最根本的區別。
淺拷貝與深拷貝的區別
數據分為基本數據類型(String, Number, Boolean, Null, Undefined,Symbol)和對象數據類型。
基本數據類型的特點:直接存儲在棧(stack)中的數據。
引用數據類型的特點:存儲的是該對象在棧中引用,真實的數據存放在堆內存里。
引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址後從堆中獲得實體。
深拷貝和淺拷貝是只針對Object和Array這樣的引用數據類型的。
深拷貝和淺拷貝的示意圖大致如下:
淺拷貝只複製指向某個對象的指針,而不複製對象本身,新舊對象還是共享同一塊內存。但深拷貝會另外創造一個一模一樣的對象,新對象跟原對象不共享內存,修改新對象不會改到原對象。
當我們把一個對象賦值給一個新的變量時,賦的其實是該對象的在棧中的地址,而不是堆中的數據。也就是兩個對象指向的是同一個存儲空間,無論哪個對象發生改變,其實都是改變的存儲空間的內容,因此,兩個對象是聯動的。
淺拷貝是按位拷貝對象,它會創建一個新對象,這個對象有着原始對象屬性值的一份精確拷貝。如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內存地址(引用類型),拷貝的就是內存地址 ,因此如果其中一個對象改變了這個地址,就會影響到另一個對象。即默認拷貝構造函數只是對對象進行淺拷貝複製(逐個成員依次拷貝),即只複製對象空間而不複製資源。
我們先來看兩個例子,對比賦值與淺拷貝會對原對象帶來哪些改變?
上面例子中,obj1是原始數據,obj2是賦值操作得到,而obj3淺拷貝得到。我們可以很清晰看到對原始數據的影響,具體請看下錶:
Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,然後返回目標對象。但是 Object.assign()進行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。
修改新對象會改到原對象:
同樣修改新對象會改到原對象:
原數組的元素會按照下述規則拷貝:
如果該元素是個對象引用(不是實際的對象),slice 會拷貝這個對象引用到新的數組裡。兩個對象引用都引用了同一個對象。如果被引用的對象發生改變,則新的和原來的數組中的這個元素也會發生改變。
對於字符串、數字及布爾值來說(不是 String、Number 或者 Boolean 對象),slice 會拷貝這些值到新的數組裡。在別的數組裡修改這些字符串或數字或是布爾值,將不會影響另一個數組。
可能這段話晦澀難懂,我們舉個例子,將上面的例子小作修改:
這種方法雖然可以實現數組或對象深拷貝,但不能處理函數。
這是因為JSON.stringify() 方法是將一個JavaScript值(對象或者數組)轉換為一個 JSON字符串,不能接受函數。
該函數庫也有提供_.cloneDeep用來做 Deep Copy。
PHP對象的淺複製與深複製的實例詳解
PHP對象的淺複製與深複製的實例詳解
最近在看原型模式時注意到這個問題~~PHP中對象
‘=’
與‘clone’的區別
實例代碼:
//聚合類
class
ObjA
{
public
$num
=
0;
public
$objB;//包含的對象
function
__construct()
{
$this-objB
=
new
ObjB();
}
//只有實現了下面方法聚合類
才能實現深複製
/*function
__clone()
{
$this-objB
=
clone
$this-objB;
}*/
}
class
ObjB
{
public
$num2
=
0;
}
//原型對象
$objA
=
new
ObjA();
//複製對象(‘=’複製引用)
$objA2
=
$objA;
$objA2-num
=
2;
//隨着$objA2-num的變化
$objA-num也變化了
print_r($objA-num.’br/’);//結果為2
print_r($objA2-num.’br/’);//結果為2
//複製對象(‘clone’關鍵字克隆)
$objA3
=
clone
$objA;
$objA3-num
=
4;
//隨着$objA3-num的變化
$objA-num沒有變化
print_r($objA-num.’br/’);//結果為2
print_r($objA3-num.’br/’);//結果為4
//但是clone的對象(是聚合類)中包含其他對象時所包含的對象(objB)複製的是引用
$objA3-objB-num2
=
7;
print_r($objA3-objB-num2.’br/’);//結果是7
print_r($objA-objB-num2.’br/’);//結果是7/pre
如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
深複製(Deep Copy)、淺複製(Shallow Copy)、copy、mutableCopy
1.屬性中copy與strong特性的區別
copy:
創建一個對象的副本,在創建的那一刻新對象與原始對象內容相同。
新的對象引用計數為1,與原始對象引用計數無關,且原始對象引用計數不會改變。
使用copy創建的新對象也是 強引用 ,使用完成後需要負責釋放該對象。
copy特性可以減少對象對上下文的依賴。新對象、原始對象中任一對象的值改變不會影響另一對象的值。
要想設置該對象的特性為copy,該對象必須遵守NSCopying協議,Foundation類默認實現了NSCopying協議,所以只需要為自定義的類實現該協議即可。
strong:
創建一個強引用的指針,引用對象引用計數加1。
strong特性表示兩個對象內存地址相同(建立一個指針,進行指針拷貝),內容會一直保持相同,直到更改一方內存地址,或將其設置為nil。
如果有多個對象同時引用一個屬性,任一對象對該屬性的修改都會影響其他對象獲取的值。
2.淺複製與深複製
對象的拷貝有淺複製和深複製兩種方式。淺複製只複製指向對象的指針,並不複製對象本身;深複製是直接複製整個對象到另一塊內存中。即淺複製是複製指針,深複製是複製內容。
NSObject提供了copy和mutableCopy 方法,copy複製後對象是不可變對象(immutable),mutableCopy複製後的對象是可變對象(mutable),與原始對象是否可變無關。
深拷貝和淺拷貝最根本的區別:是否真正獲取一個 對象的複製實體 ,而不是引用。
淺拷貝:修改堆內存中的同一個值。
深拷貝:修改堆內存中的不同的值。
2.1非集合類對象的copy與mutableCopy
非集合類對象指的是NSString、NSNumber之類的對象,深複製會複製引用對象的內容,而淺複製只複製引用這些對象的指針。因此,如果對象A被淺複製到對象B,對象B和對象A引用的是同一內存地址的實例變量或屬性。
2.1.1不可變對象的copy與mutableCopy
2.1.2可變對象的copy與mutableCopy
2.2容器類對象的深複製、淺複製
容器類對象指NSArray、NSDictionary等。
對於容器類,需要探討的是複製後容器內元素的變化,而非容器本身內存地址是否發生了變化。
2.2.1容器類對象的淺複製
當對集合進行淺複製時,將複製原始集合中元素指針到新的集合,即原始集合中元素引用計數加一。
2.2.2容器類對象的深複製
有兩種方式對容器類對象進行深複製:
一:使用initWithArray: copyItems:類型方法,其中,第二個參數為YES。
二:使用歸檔、解檔。
2.3自定義對象的深複製、淺複製
3.修改指針指向
總結:
淺拷貝儘可能少的複製對象,集合的淺拷貝副本只是集合結構的副本,而不是集合內元素的副本。淺拷貝獲得的副本與原始集合共享各個元素。
深拷貝複製一切內容。集合的深拷貝會複製集合的結構和元素,但如果集合內元素也是集合,則涉及到一層深拷貝、完全深拷貝。
參考:
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/189438.html