2009-08-18 66 views
0

我試圖簡化和註釋下面給我頭痛的代碼。它證明了我的問題。簡而言之,我有兩個單獨的堆棧,我試圖從一個堆棧彈出。出於某種原因,當你彈出其中一個堆棧時,它似乎也彈出另一個堆棧?!這是否是設計的,如果是這樣,爲什麼以及如何解決它?爲什麼從一個堆棧彈出實際上是從多個單獨的堆棧彈出的?

...還是我只是在盡一個布偶? (不要回答那個)

Public Class Form1 
Public _stackMaster As New Stack 
Public _stackCopy As New Stack 
Public _strPopped As String 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    _stackMaster.Push("line1") 
    _stackMaster.Push("line2") 
    _stackMaster.Push("line3") 
    MsgBox("Before copying the Master stack to the Copy stack." & vbCrLf & "_stackMaster.Count=" & _stackMaster.Count & vbCrLf & "_stackCopy.Count=" & _stackCopy.Count) 
    _stackCopy = _stackMaster 
    MsgBox("After copying the Master stack to the Copy stack." & vbCrLf & "_stackMaster.Count=" & _stackMaster.Count & vbCrLf & "_stackCopy.Count=" & _stackCopy.Count) 
    _strPopped = _stackCopy.Pop 
    MsgBox("After popping a string from the Copy stack." & vbCrLf & "_stackMaster.Count=" & _stackMaster.Count & vbCrLf & "_stackCopy.Count=" & _stackCopy.Count & vbCrLf & "Why do both counts decrease?? Aren't they separate stacks?") 
    End 
End Sub 
End Class 

回答

4
_stackCopy = _stackMaster 

這條線是你的罪魁禍首。 _stackCopy_stackMaster各自參考堆棧實例。當你將一個分配給另一個時,你正在使它們每個參考相同的實例。你想要做的是克隆_stackMaster並將其分配給_stackCopy

_stackCopy = _stackMaster.Clone() 
+0

這絕對是正確的。但是,沒有任何人知道爲什麼嗎?如果我有兩個整數和我使用類似的賦值語句,它複製值,而不是參考。是在vb中聲明一個棧基本上只是聲明一個指針? – Chris 2009-08-19 12:50:51

+0

.NET有兩種對象類型:引用類型和值類型。值類型在堆棧上分配(並從基類ValueType派生),而引用類型在堆上分配(並從基類對象派生),並在堆棧上分配一個引用(基本上是一個託管指針)。基元(Int32,Single,Double等)是值類型,因此直接分配。 'Stack'是一個引用類型,因此'Stack'變量都只是引用。 – 2009-08-19 17:27:30

1

這是因爲您只是將引用分配給_stackCopy。這條線不會複製棧,它只是複製引用到實際對象:

_stackCopy = _stackMaster 

在.NET中,你有參考和值類型。如果將其分配給另一個變量,則值類型將被複制。對於引用類型,您複製引用,但仍只有一個對象。

所以,是的,你所看到的行爲,是由設計。

3

你碰到的值類型和引用類型之間的差異。 Stack是一個引用類型,這意味着將_stackCopy分配給_stackMaster不會複製堆棧,而只是將引用複製到內存中完全相同的位置。

當你正在執行的最後流行,你只在一個堆棧執行,但在你的代碼,_stackCopy和_stackMaster點完全相同的對象這一點。

你可以解決這個做(在C#):

object[] values = _stackMaster.ToArray(); 
for(int i = 0; i < values.Length; i++) 
{ 
    _stackCopy.Push(values[i]); 
} 
+0

+1對於實際解釋複製參考實際上意味着什麼和提供解決方案。 – 2009-08-18 20:32:08

+0

如果我可以,我會+1,但我不能,因爲我還是菜鳥:(Thx的BG信息,非常實用。 – Kez 2009-08-19 18:44:08

0

我沒用過VB.net不多,但它似乎你是不是做了深刻的副本,你是通過參考之用複製。這裏有一個比喻:

你的第一個堆棧,你有一個包含項的複選框。當您創建副本時,您沒有獲得另一個方框並放入相同的項目,而是創建一個標誌,指出「查看該方框」並指向您的原始副本。因此,當你拿起盒子的東西,當你按照標誌當然一個項目將失蹤。

嘗試谷歌搜索「按引用傳遞」。它們在面嚮對象語言中使用很多。