我试图简化和注释下面给我头疼的代码。它证明了我的问题。简单地说,我有两个独立的堆栈,我试图从一个堆栈弹出。出于某种原因,当你弹出其中一个堆栈时,它实际上似乎也会弹出另一个堆栈?!这是设计,如果是这样,为什么以及如何解决它?
......或者我只是一个布偶? (不要回答那个)
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
答案 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,但看起来你没有做深层复制,你只是通过引用复制。这是一个类比:
使用第一个堆栈,您有一个包含项目的框。当您创建副本时,您没有获得另一个框并将相同的项目放入其中,而是创建一个标记,上面写着“查看该框”并指向您的原始副本。因此,当你拿出盒子的东西时,当你按照标志当然会丢失一个项目。
尝试谷歌搜索“通过引用传递”。它们在面向对象语言中被大量使用。