如何在VB6中克隆一个对象

5

我想自动克隆一个对象,而不必实例化一个新对象并手动复制每个变量。

我记得以前(当我每天都在做VB6时)我用PropertyBag的方法克隆对象,这非常酷。但是我已经丢失了代码,也不记得如何操作了。

有人还记得或者有其他方法吗?


这些是自定义类还是内置对象? - Quintin Robinson
4个回答

4

我过去使用的方法是将所有实例变量放在一个UDT中。只要您保持UDT最新,就可以使用单个方法/语句复制类的数据。

以“Person”类为例,这里有一个简单的示例:

Private Type tPerson
    ID As Long
    FirstName As String
    LastName As String
End Type  

Private m_Person As tPerson  

Public Sub InitPerson(ID As Long, FirstName As String, LastName As String)
    m_Person.ID = ID
    m_Person.FirstName = FirstName
    m_Person.LastName = LastName
End Sub  

Friend Sub SetData(PersonData As tPerson)
    m_Person = PersonData

End Sub  

Public Function GetClone() As Person
    Dim p As New Person
    p.SetData m_Person

    Set GetClone = p

End Function  

Public Property Get FirstName() As String
    FirstName = m_Person.FirstName

End Property  

尝试这段代码:

Dim p As New Person
p.InitPerson 1, "MyName", "MyLastName"

Dim p2 As Person
Set p2 = p.GetClone

MsgBox p2.FirstName

如果您将所有实例变量都放入UDT中而不是单独声明它们,那么您可以拥有一个非常少维护的简单克隆方法。

另一个优点是您可以将UDT放入文件句柄中,以便快速序列化到磁盘。

Public Sub Save(filePathName As String)
    Dim f As Integer
    f = FreeFile()

    Open filePathName For Binary Access Write Lock Read Write As #f
        Put #f, , m_Person
    Close #f

End Sub

一个穷人的序列化解决方案,哈哈 :-)

OP问如何克隆一个对象而不是类型。它们是非常不同的东西。此外,这段代码是错误的。您不能声明类型“As New”,也不能“Set”它。这些关键字保留用于引用类型。用户定义的类型是值类型。克隆就像“udt1 = udt2”一样简单。对象是引用类型,使得克隆更加繁琐。 - raven
@raven 我会尝试运行它,它会成功的。我只是实例化了Person类,没有在UDT上执行New操作。我正在使用该类型作为传输方式,也许您可以再次阅读代码? - user45886
@Joppe:你说得对。我的错。我没有仔细阅读。 - raven
@raven 没问题,没问题,这种事情经常发生 :-) - user45886

4

请问 this 是您正在寻找的内容吗?以下是文章的原文,供参考。

使用 PropertyBag 序列化数据

将数据放入 PropertyBag 对象中,然后读取 PropertyBags Contents 属性,即可快速地序列化数据。该属性实际上是一个字节数组,它是您的 PropertyBag 对象中数据的串行表示形式。您可以将这个字节数组用于许多目的,包括在 DCOM 上进行高效的数据传输:

Private Function PackData() As String
    Dim pbTemp  As PropertyBag

    'Create a new PropertyBag object
    Set pbTemp = New PropertyBag
    With pbTemp
        'Add your data to the PB giving each item a 
        'unique string key
        Call .WriteProperty("FirstName", "John")
        Call .WriteProperty("MiddleInitial", "J")
        Call .WriteProperty("LastName", "Doe")

        'Place the serialized data into a string 
        'variable.
        Let PackData = .Contents
    End With

    Set pbTemp = Nothing
End Function

要检索序列化数据,只需创建一个新的PropertyBag对象,并将序列化字符串设置为其Contents属性。在将其分配给Contents属性之前,将字符串转换为字节数组:
Private Sub UnPackData(sData As String)
    Dim pbTemp  As PropertyBag
    Dim arData()    As Byte

    'Convert the string representation of the data to 
    'a Byte array
    Let arData() = sData

    'Create a new PropertyBag object
    Set pbTemp = New PropertyBag
    With pbTemp
        'Load the PropertyBag with data
        Let .Contents = arData()

        'Retrieve your data using the unique key
        Let m_sFirstName = .ReadProperty("FirstName")
        Let m_sMiddleInitial = _
            .ReadProperty("MiddleInitial")
        Let m_sLastName = .ReadProperty("LastName")
    End With

    Set pbTemp = Nothing
      End Sub

迈克·库尔茨,宾夕法尼亚州麦基斯罗克斯


我猜,它不像我记得的那么顺畅。基本上仍然涉及大量的低级代码。谢谢。 - AngryHacker

1

1
我的应用程序框架中的每个对象都有一个读取和存储方法。我的做法是向它们传递一个流,该流写入到一个字节数组并存储该字节数组。虽然这样做不能消除处理每个属性的需求,但只需要处理一次读取和一次写入就可以了。
另一种选择是使用像Darrel Miller所说的属性包,但您仍然必须单独处理每个属性。如果您已经具有读和存储功能,则我的建议应该能够节省一些时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接