Class VB6中对象的赋值
我试图通过赋值语句在VB6中创建两个相同的对象;像这样的Class VB6中对象的赋值,class,vb6,Class,Vb6,我试图通过赋值语句在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.mem
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
...
?
edit2Scott 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
或者我必须一次复制一个成员的对象
Set myobj2 = new Class1
myobj2.mem1 = myobj1.mem1
...
不幸的是,是的
<> P> >在C++中编写COM服务器是可能的(但技术上非常困难),使用IDISPoT接口将复制每个属性的值,但实际上这是高庙宇编程,如果我必须这样做,我不知道我是否能做,但我会看到像10天的工作。(我知道如何在C++中实现COM,我还需要调查,看看ATL框架是否有什么帮助)。
我在Vb3、4、5和6上工作了大约10年(亲自动手,每周5天)除了手动实现诸如Memento和Save&Store之类的序列化模式之外,从来没有找到一个好的方法来实现这一点,这实际上可以归结为一次复制每个成员的奇特方式。与许多现代语言一样,VB6有值类型和引用类型。类定义引用类型。另一方面,您的基本类型像
Integer
这样的E是值类型
基本区别在于分配:
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通过强制使用s来明确这一点et
关键字。大多数其他现代语言不需要这个
现在,您可以创建自己的值类型(在VB6中称为用户定义类型,但在大多数其他语言中称为结构)
类和用户定义类型(类是引用类型,UDT是值类型除外)之间的区别在于,类可以包含UDT无法包含的行为(方法和属性)。如果您只是查找记录类型类,那么UDT可能是您的解决方案
您可以混合使用这些技术。假设您需要一个类,因为您有某些行为和计算要与数据一起包含。您可以使用来保存UDT中对象的状态:
Type MyMemento
Value1 As Integer
Value2 As String
End Type
在类中,确保所有内部状态都存储在类型为MyMemento
的私有成员中。编写属性和方法,使它们仅使用该私有成员变量中的数据
现在,复制对象很简单。只需在类上编写一个名为copy()
的新方法,该方法将返回类的新实例,并使用其自己的memento副本对其进行初始化:
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@Scott Whitlock,我无法使您的代码正常工作,但如果它正常工作,那就太好了 我创建了一个常规模块,在其中放置memento类型
Type MyMemento
Value1 As Integer
Value2 As String
End Type
然后我用代码创建了一个名为MyClass的类模块
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
Result.SetMemento(Memento)
Set Copy = Result
End Function
最后,我尝试在另一个常规模块中调用copy函数,如下所示
Sub Pruebas()
Dim Primero As MyClass, segundo As MyClass
Set Primero = New MyClass
Set segundo = New MyClass
Set segundo = Primero.Copy
End Sub
我得到了信息(下图):编译错误:El tipo de agumento de ByRef no
这是一张图片(缺少10点,所以这里是链接):
我无法用英语传达信息,我住在西班牙
请您提供一个VBA Excel中的示例,我一直在努力实现这一点
谢谢你的工作
===============================================
编辑:问题已解决:
问题出现在“Result.SetMemento(Memento)”行上,在VBA中,需要用“Call”调用它
它工作得很好,谢谢Scott Whitlock,你是个天才这个问题可能会引起兴趣:我喜欢如何在兴趣问题中,第二个最好的答案只是对这个问题答案的引用!:)+1我在VBx中见过的最干净的Memento实现,我从未考虑过使用类型作为快捷方式。干得好,那个人@二元烦恼-谢谢!我知道我的l33t VB6技能总有一天会派上用场。。。哈哈.)谢谢你的回答;我一直在尝试。我不得不将
类型
定义私有,并将Me.
从Me.Memento
中删除,但我无法获得结果。Memento
要编译的部分;它响应“未找到方法或数据成员”。我能编译它的唯一方法是将所有成员公开,并一次分配一个成员。我错过什么了吗?(在问题中添加了您的代码的我的版本。)@Brian Hooper-抱歉,我的.NET再次与VB6混合。您必须在类上创建一个SetMemento
方法。我会更新我的答案。如果你把它公开为Friend
,我想你也得把你的类型定义为Friend
。谢谢你,它现在玩得很开心。我觉得没有必要让类型
成为朋友
。实际上,你不需要呼叫
关键字,但是你可以