在VB6中分配对象

Bri*_*per 26 vb6 class

我试图通过赋值语句在VB6中创建两个相同的对象; 像这样的东西......

Dim myobj1 As Class1
Dim myobj2 As Class1

Set myobj1 = New Class1
myobj1.myval = 1
Set myobj2 = myobj1
Run Code Online (Sandbox Code Playgroud)

很明显,这不会创建两个对象,而是两个对同一对象的引用,这不是我所追求的.有没有办法以这种方式创建第二个对象,或者我是否必须一次复制一个成员对象...

Set myobj2 = new Class1
myobj2.mem1 = myobj1.mem1
...
Run Code Online (Sandbox Code Playgroud)

编辑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
Run Code Online (Sandbox Code Playgroud)

然后,然后在代码中执行赋值...

Set mysecondobj = myfirstobj.Copy
Run Code Online (Sandbox Code Playgroud)

Sco*_*ock 38

与许多现代语言一样,VB6具有值类型和引用类型.类定义引用类型.另一方面,您的基本类型Integer是值类型.

作业的基本区别在于:

Dim a as Integer
Dim b as Integer
a = 2
b = a
a = 1
Run Code Online (Sandbox Code Playgroud)

结果是a1并且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
Run Code Online (Sandbox Code Playgroud)

其结果是,这两个a.Value1b.Value1是1.这是因为对象的状态被存储在堆,而不是在堆栈.只有对象的引用存储在堆栈中,因此会Set b = a覆盖引用.有趣的是,VB6通过强制使用Set关键字来明确这一点.大多数其他现代语言不需要这样.

现在,您可以创建自己的值类型(在VB6中,它们被称为用户定义类型,但在大多数其他语言中,它们被称为结构或结构).这是一个教程.

类和用户定义类型之间的差异(除了作为引用类型的类和作为值类型的UDT)是一个类可以包含UDT不能的行为(方法和属性).如果您只是在寻找记录类型,那么UDT可能就是您的解决方案.

您可以混合使用这些技术.假设您需要一个类,因为您希望包含某些行为和计算以及数据.您可以使用memento模式来保存UDT内对象的状态:

Type MyMemento
    Value1 As Integer
    Value2 As String
End Type
Run Code Online (Sandbox Code Playgroud)

在您的班级中,确保所有内部状态都存储在类型的私有成员中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
Run Code Online (Sandbox Code Playgroud)

Friend隐藏的仅仅是它的东西你的项目之外,因此它不会做很多工作来隐藏SetMemento子,但是这一切都可以用VB6做.

HTH

  • 我在VBx中看到的+1 Cleanest Memento实现,我从未考虑过使用类型作为快捷方式.做得好那个男人! (7认同)