我有这段代码:
Call MakeRoomForArrayItem(interAll, 0)
interAll(0).StartY = tempStartY
interAll(0).K = tempK
在第一行中,我成功地创建了一个新的细长interAll()。
然后我希望第二行和第三行仅影响interAll(0),但它们对interAll(1)执行相同的更改。为什么是这样?我没有为interAll(1)成功创建新对象吗?
Sub MakeRoomForArrayItem(ItemArray As Variant, ByVal ItemElement As Integer)
Dim i As Integer
ReDim Preserve ItemArray(LBound(ItemArray) To UBound(ItemArray) + 1)
For i = UBound(ItemArray) - 1 To ItemElement Step -1
Set ItemArray(i + 1) = ItemArray(i)
Next
'Erase values in object ItemArray(ItemElement) would be nice
End Sub
我在其他情况下成功使用了相同的功能。它可能与调用函数中缺少声明有关吗?
编辑:我通过添加
解决了问题Set interval = New CInterval
Set interAll(0) = interval
你能告诉我这里到底发生了什么事,以便我不再犯同样的错误吗?
答案 0 :(得分:1)
执行此操作时:
Set ItemArray(i + 1) = ItemArray(i)
您正在复制参考,而不是值。因此,在循环结束时,当i=0
时,此行所说的是“将对ItemArray(0)
中对象的引用复制到位置1”。因此ItemArray(0)
和ItemArray(1)
都包含指向同一对象实例的引用。您应该能够使用调试器确认这一点。
答案 1 :(得分:1)
这取决于您传入MakeRoomForArrayItem
的变量类型。如果您的数组持有值类型变量,例如Integer或Boolean,那么它将起作用,因为赋值语句
Set ItemArray(i + 1) = ItemArray(i)
正在复制一个值。但是,如果您使用的是通过引用传递的变量,那么您不会复制其值,而是复制对该变量的引用。在这种情况下,您似乎传递了一个类变量,该变量将通过引用传递。
编辑:当你调用New CInterval
时,你实际上分配了一个新变量,而不是复制对前一个变量的引用。这就是你的修复工作的原因。如果没有你的修复,你只在内存中有一个“槽”来保存一个值,但你的数组多次引用该内存。修复之后,内存中的“插槽”与调用New CInterval
的内容一样多,并且数组的每个元素都引用了新的内存位置。
以下代码可能会有所帮助:
Set interval1 = New CInterval ' you have a single CInterval instance
Set interval2 = New CInterval ' changes to interval1 or interval2 do not affect each other
Set interval3 = interval2 ' changes to interval3 also make changes to interval2,
' because they are the same object.
Dim arr as CInterval(3)
' Create a single array that has 3 elements,
' which will hold 3 references to CInterval instances.
' Those references may or may not be to the same actual CInterval instance.
Set arr(0) = interval1 ' the first element of the array references the first object instance
Set arr(1) = interval1 ' the second element of the array also references the first object instance
Set arr(2) = interval2 ' the third element of the array references the second object instance.
' Changes to this element will affect both interval2 and interval3, because they are references to the same object in memory.