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斯科特·惠特洛克更新了他的出色答案,并将他的修改纳入了这个现在工作的代码段。
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
基本的区别在于:
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可能就是你的解决方案。
您可以使用这些技术的混合。假设你需要一个Class,因为你有一些行为和计算,你想要包含数据。您可以使用memento pattern来保持UDT内的对象的状态:
Type MyMemento Value1 As Integer Value2 As String End Type
在你的课堂上,确保你所有的内部状态都存储在MyMemento类型的私人成员中。编写您的属性和方法,以便它们只使用该私有成员变量中的数据。
现在制作一个对象的副本很简单。只需在您的类中复制一个新的方法(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
朋友只将它从项目外面的东西中隐藏起来,所以隐藏SetMemento子文件并没有太多的东西,但是它可以用VB6做。
HTH