我试图通过赋值语句在VB6中创建两个相同的对象;像这样的东西...
Dim myobj1 As Class1
Dim myobj2 As Class1
Set myobj1 = New Class1
myobj1.myval = 1
Set myobj2 = myobj1
很明显,这不会创建两个对象,而是创建对同一对象的两个引用,这不是我所追求的。有没有办法以这种方式创建第二个对象,或者我是否必须一次复制一个成员......
Set myobj2 = new Class1
myobj2.mem1 = myobj1.mem1
...
?
编辑 2 Scott Whitlock 更新了他的出色答案,我已将他的更改合并到这个现在可用的代码片段中。
Private Type MyMemento
Value1 As Integer
Value2 As String
End Type
Private Memento As MyMemento
Public Property Let myval(ByVal newval As Integer)
Memento.Value1 = newval
End Property
Public Property Get myval() As Integer
myval = Memento.Value1
End Property
Friend Property Let SetMemento(new_memento As MyMemento)
Memento = new_memento
End Property
Public Function Copy() As Class1
Dim Result As Class1
Set Result = New Class1
Result.SetMemento = Memento
Set Copy = Result
End Function
然后在代码中执行分配,从而......
Set mysecondobj = myfirstobj.Copy
最佳答案
与许多现代语言一样,VB6 也有值类型和引用类型。类定义引用类型。另一方面,像 Integer
这样的基本类型是值类型。
基本区别在于分配:
Dim a as Integer
Dim b as Integer
a = 2
b = a
a = 1
结果是 a
为 1,b
为 2。这是因为值类型中的赋值会生成副本。这是因为每个变量都在堆栈上为值分配了空间(在 VB6 中,整数在堆栈上占用 2 个字节)。
对于类,它的工作方式有所不同:
Dim a as MyClass
Dim b as MyClass
Set a = New MyClass
a.Value1 = 2
Set b = a
a.Value1 = 1
结果是,a.Value1
和 b.Value1
都为 1。这是因为对象的状态存储在堆中,而不是堆栈中。只有对象的引用存储在堆栈上,因此Set b = a
会覆盖该引用。有趣的是,VB6 通过强制您使用 Set
关键字对此进行了明确说明。大多数其他现代语言不需要这个。
现在,您可以创建自己的值类型(在 VB6 中,它们称为“用户定义类型”,但在大多数其他语言中,它们称为“结构”或“结构体”)。这是 tutorial .
类和用户定义类型之间的区别(除了类是引用类型而 UDT 是值类型之外)是类可以包含 UDT 不能包含的行为(方法和属性)。如果您只是在寻找记录类型类,那么 UDT 可能是您的解决方案。
您可以混合使用这些技术。假设您需要一个类,因为您希望将某些行为和计算与数据一起包含在内。您可以使用 memento pattern保存 UDT 内对象的状态:
Type MyMemento
Value1 As Integer
Value2 As String
End Type
在您的类中,请确保您的所有内部状态都存储在MyMemento
类型的私有(private)成员中。编写您的属性和方法,以便它们仅使用该私有(private)成员变量中的数据。
现在制作对象的副本很简单。只需在类上编写一个名为 Copy()
的新方法,该方法返回类的新实例并使用其自己的备忘录副本对其进行初始化:
Private Memento As MyMemento
Friend Sub SetMemento(NewMemento As MyMemento)
Memento = NewMemento
End Sub
Public Function Copy() as MyClass
Dim Result as MyClass
Set Result = new MyClass
Call Result.SetMemento(Memento)
Set Copy = Result
End Function
Friend
仅对项目外部的内容隐藏它,因此它对隐藏 SetMemento
子项没有多大作用,但这就是您使用 VB6 所能做的。
HTH
关于class - VB6中对象的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4805475/