在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.Value1和b.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认同)