C 淺拷貝與深拷貝區別

2021-09-06 01:20:45 字數 3494 閱讀 4418

也許會有人這樣解釋c# 中淺拷貝與深拷貝區別:

淺拷貝是對引用型別拷貝位址,對值型別直接進行拷貝。

不能說它完全錯誤,但至少還不夠嚴謹。比如:string 型別咋說?

其實,我們可以通過實踐來尋找答案。

首先,定義以下型別:

int 、string 、enum 、struct 、class 、int[ ] 、string[ ]

**如下:

//列舉

public

enum

myenum

//結構體

public

struct

mystruct}//

類class

myclass}//

icloneable:建立作為當前例項副本的新物件。

class

democlass

:icloneable

;public

string

arrstring

=new

string

;//返回此例項副本的新物件

public

object

clone()

} 注意:

icloneable 介面:支援轉殖,即用與現有例項相同的值建立類的新例項。

memberwiseclone 方法:建立當前 system.object 的淺表副本。

接下來,構建例項a,並對例項a轉殖產生乙個例項b

然後,改變例項b的值,並觀察例項a的值會不會被改變。

**如下:

class

淺拷貝與深拷貝b:"

,a._int,b.

_int);

b._string="

2";console

.writeline("

string

\ta:b:"

,a._string,b.

_string);

b._enum

=myenum

._2;

console

.writeline("

enum

\t\t

a:b:",

(int)a

._enum,

(int)b

._enum);

b._struct

._int=2

;console

.writeline("

struct

\ta:b:"

,a._struct

._int,b.

_struct

._int);

b._class

._string="

2";console

.writeline("

class

\t\t

a:b:",

a._class

._string,b.

_class

._string);

b.arrint[0

]=2;

console

.writeline("

intarray

\ta:b:"

,a.arrint[0

],b.

arrint[0

]);b

.arrstring[0

]="2

";console

.writeline("

stringarray

\ta:b:"

,a.arrstring[0

],b.

arrstring[0

]);console

.readkey()

;}}

結果如下:

從最後的輸出結果,我們得知:

對於內部的class 物件和陣列,則copy 乙份位址。[ 改變b 時,a也被改變了 ]

而對於其它內建的int / string / enum / struct / object 型別,則copy 乙份值。

有一位網友說:string 型別雖然是引用型別,但是很多情況下.net 把string 做值型別來處理,我覺得string 應該也是按照值型別處理的。

這說明他對string 型別還不夠了解。

可以肯定的是:string 一定是引用型別。那它為什麼是深拷貝呢?

如果你看一下string 型別的源**就知道了:

//表示空字串。此字段為唯讀。

public

static

readonly

string

empty;

答案就在於 string 是 readonly 的,當改變 string 型別的資料值時,將重新分配了記憶體位址。

下面引用一段網友的**:

vseen[ aloner ]

的個人陋見:

public

class

student

淺拷貝:student

a淺拷貝出

student

b,name和age擁有新的記憶體位址,但引用了同乙個

classroom。

深拷貝:student

a淺拷貝出

student

b,name和age擁有新的記憶體位址,並且a

.classroom

的記憶體位址不等於b.

classroom。

其實俗點講,有點像:

public

object

clone()

淺拷貝:給物件拷貝乙份新的物件。

淺拷貝的定義 —— 只對值型別(或string)型別分配新的記憶體位址。

深拷貝:給物件拷貝乙份全新的物件。

深拷貝的定義 —— 對值型別分配新的記憶體位址,引用型別、以及引用型別的內部字段分配的新的位址。

我是這麼定義的:淺拷貝,換湯不換藥。

注意:

1、在 .net 程式中,應該避免使用 icloneable 介面。

因為通過該介面無法判斷究竟是淺拷貝還是深拷貝,這會造成誤解或誤用。

2、深拷貝應該複製該物件本身及通過該物件所能到達的完整的物件圖,淺拷貝只複製物件本身(就是該物件所表示的在堆中的一塊連續位址中的內容)。

個人愚見:

clone :深層拷貝,拷貝到了指標指向的記憶體塊的值。

淺拷貝:僅僅拷貝了指標的內容。(只是給乙個物件多起了個名字,所以,當改變拷貝的某個屬性的時候,原物件的對應屬性亦會改變)。

C 淺拷貝與深拷貝區別

也許會有人這樣解釋c 中淺拷貝與深拷貝區別 淺拷貝是對引用型別拷貝位址,對值型別直接進行拷貝。不能說它完全錯誤,但至少還不夠嚴謹。比如 string 型別咋說?其實,我們可以通過實踐來尋找答案。首先,定義以下型別 int string enum struct class int string 如下 ...

c 深拷貝與淺拷貝區別

深拷貝和淺拷貝最根本的區別在於是否真正獲取乙個物件的複製實體,而不是引用。假設b複製了a,修改a的時候,看b是否發生變化 如果b跟著也變了,說明是淺拷貝,拿人手短!修改堆記憶體中的同乙個值 如果b沒有改變,說明是深拷貝,自食其力!修改堆記憶體中的不同的值 淺拷貝 shallowcopy 只是增加了乙...

C 深拷貝與淺拷貝區別

c 深拷貝與淺拷貝區別 深拷貝和淺拷貝最根本的區別在於是否真正獲取乙個物件的複製實體,而不是引用。假設b複製了a,修改a的時候,看b是否發生變化 如果b跟著也變了,說明是淺拷貝,拿人手短!修改堆記憶體中的同乙個值 如果b沒有改變,說明是深拷貝,自食其力!修改堆記憶體中的不同的值 淺拷貝 shallo...