7

我知道类 Object 在面向对象的编程语言(如 Java)中位于类层次结构的顶部。我还了解到您在 .NET 中有引用类型和值类型。我也理解基于 C 语言的类型定义。

尽管如此; 我正在努力理解 VB6 中的对象是什么( http://msdn.microsoft.com/en-us/library/aa338034%28v=vs.60%29.aspx )以及究竟是什么变体。什么是变体?以及如何在 VB6 中实现对象?

4

2 回答 2

10

VB6 使用的所有对象都是 COM 对象。COM 对象本质上是一个可变长度的数据结构,其可变长度头包含任意数量的指向 VTable 的 32 位指针,而连续的字节包含对象的实例数据。例如,

Bytes
0-3    VTable1 pointer
4-7    VTable2 pointer
8-11   VTable3 pointer
...
       Instance data

VTable 是一个由 32 位指针组成的数组,指向函数,所有这些函数都被传递一个“this”实例指针。

Bytes
0-3    Func1(this, ..., ...)
4-7    Func2(this, ..., ...)
8-11   Func3(this, ..., ...)
...

唯一的其他规范是所有 VTable必须从 IUnknown 继承,即前三个函数必须是:

QueryInterface()
AddRef()
Release()

本质上,QueryInterface() 允许您查明 COM 对象是否支持特定接口(由 UUID 表示)。AddRef() 允许对象编写器增加内部引用计数。Release() 允许对象写入器减少引用计数器,当计数为零时销毁对象。您永远不会在 VB 中调用这些方法——编译器会为您添加这些调用(VB6 的优点之一)。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/ms680509(v=vs.85).aspx 。

VB“对象”类型是对支持 IDispatch 接口的对象的引用(参见http://msdn.microsoft.com/en-us/library/windows/desktop/dd318520(v=vs.85).aspx) . 这就是允许您在 VB 和 VBScript 中进行后期绑定的原因。用 VB6 编写的所有对象都会自动实现从 IDispatch 继承的接口。这称为双接口,因为它支持早期和后期绑定。

请注意,COM 中没有内置直接类型系统。但是,您可以选择支持 ITypeInfo 接口,它允许您的对象的用户访问您想要添加的有关对象的信息(使用使用类型库来存储此信息的默认实现更容易)。

正如 Bob Riemersma 所提到的,Variant 类型实际上是一个 16 字节的结构,它有一个 2 字节的整数 (vt),表示封装了什么自动化类型,后 8 个字节可用于包含最多 8 个值类型字节,或指向另一种类型的 32 位指针。VB 使用其内部函数在 VB 类型和 Variants 之间进行所有必要的转换,以及所有必要的内存分配和释放。通过将指向对象的指针复制到 Variant 中并调用对象的 AddRef() 方法,变体可以包含对 COM 对象的引用。

于 2012-04-11T14:30:59.483 回答
5

让我把它分解成不同的问题:

首先,VB6 不是 VB.Net,不使用 .Net 框架,而是使用较旧的 COM 框架。(不知道你是否已经知道这一点)。

其次,您的链接所指向的实际上是VB6 内置的类。尽管,是的,它称它们为“对象”。他们的术语草率。

第三,可能也是最重要的,在 VB6 中,一切都不是对象,对象甚至不是数据类型的默认或主要类别。是的,类似于 .Net 的值类型,但要少得多(大多数甚至没有运行时类型容器,只有内存中的地址)。

所以大多数数据项不是对象,因此没有类,因此没有任何类型的继承,因此没有从其他任何东西派生,因此没有“类型层次结构”,因此在“ “它们的类型层次结构的顶部”(尽管作为类/对象的东西确实拥有所有这些)。因此,您没有可用于任何其他数据类型的基本/根数据类型,这对于各种参数传递等情况都是一个问题。

变体是对这个问题的一种优先解决方案,在早期版本的 VB 中实现(早于 VB 中的对象)来解决这个问题。变体只是一个动态描述符,它包装了任何数据类型的另一个项目。当您使用它时(通常)就像您直接使用它包含的内容一样,但您实际上是通过Variant 来获取它当前碰巧包含的任何类型的数据项。

Variant 本身会跟踪其内容的数据类型是什么,并导致访问它的 VB 代码行为不同/适当(一种原始的多态性)。

如果这听起来很笨拙,而且开销很大,那么,确实如此。但在当时,当您需要处理“任何数据类型”时,它是最好的解决方案。

于 2012-04-10T20:39:27.127 回答