为什么从一个堆栈弹出实际上是从多个单独的堆栈弹出?

时间:2009-08-18 20:24:15

标签: vb.net visual-studio-2008 variables

我试图简化和注释下面给我头疼的代码。它证明了我的问题。简单地说,我有两个独立的堆栈,我试图从一个堆栈弹出。出于某种原因,当你弹出其中一个堆栈时,它实际上似乎也会弹出另一个堆栈?!这是设计,如果是这样,为什么以及如何解决它?

......或者我只是一个布偶? (不要回答那个)

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 个答案:

答案 0 :(得分:4)

_stackCopy = _stackMaster

这条线是你的罪魁祸首。 _stackCopy_stackMaster分别是引用来堆叠实例。当您将一个分配给另一个时,您将使它们各自引用相同的实例。您要做的就是克隆_stackMaster并将其分配给_stackCopy

_stackCopy = _stackMaster.Clone()

答案 1 :(得分:3)

您遇到了值类型和引用类型之间的差异。 Stack是一种引用类型,这意味着将_stackCopy分配给_stackMaster不会复制堆栈,只会将引用复制到内存中完全相同的位置。

当您执行最后一个Pop时,您只在一个堆栈上执行它,但在代码中的那一点,_stackCopy和_stackMaster指向完全相同的对象。

你可以通过做(在C#中)来解决这个问题:

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

答案 2 :(得分:1)

这是因为您只是将引用分配给_stackCopy。此行不会复制堆栈,只是将引用复制到实际对象:

_stackCopy = _stackMaster

在.NET中,您有参考和值类型。如果将值分配给另一个变量,则将复制该值类型。对于引用类型,复制引用,但仍然只有一个对象。

所以是的,你所看到的行为是设计的。

答案 3 :(得分:0)

我没有太多使用过VB.net,但看起来你没有做深层复制,你只是通过引用复制。这是一个类比:

使用第一个堆栈,您有一个包含项目的框。当您创建副本时,您没有获得另一个框并将相同的项目放入其中,而是创建一个标记,上面写着“查看该框”并指向您的原始副本。因此,当你拿出盒子的东西时,当你按照标志当然会丢失一个项目。

尝试谷歌搜索“通过引用传递”。它们在面向对象语言中被大量使用。