VB6对象和数据类型

VB6对象和数据类型,vb6,Vb6,我知道类对象在面向对象编程语言(如Java)中处于类层次结构的顶端。我还知道.NET中有引用类型和值类型。我也理解基于C语言的类型定义 尽管如此,;我正在努力理解VB6中的对象是什么( )确切的变种是什么。什么是变体?对象是如何在VB6中实现的?让我将其分解为不同的问题: 首先,VB6不是VB.Net,也不使用.Net框架,而是使用旧的COM框架。(不知道您是否已经知道这一点) 其次,您的链接指向的实际上是VB6的内置类。尽管如此,是的,它称它们为“对象”。他们这方面的术语马虎 第三,可能也是最

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

尽管如此,;我正在努力理解VB6中的对象是什么(
)确切的变种是什么。什么是变体?对象是如何在VB6中实现的?

让我将其分解为不同的问题:

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

其次,您的链接指向的实际上是VB6的内置类。尽管如此,是的,它称它们为“对象”。他们这方面的术语马虎

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

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

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

变量本身跟踪其内容的数据类型,并使访问它的VB代码表现出不同/适当的行为(一种原始的多态性)


如果这听起来像是一场混乱,而且是一个很大的开销,那么,是的。但在当时,当您需要处理“任何数据类型”时,它是最好的可用解决方案。

VB6使用的所有对象都是COM对象。COM对象本质上是一个可变长度的数据结构,其可变长度头包含任意数量的指向VTables的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, ..., ...)
...
唯一的其他规范是所有VTables必须从IUnknown继承,即前三个函数必须是:

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

有关更多详细信息,请参阅

VB“对象”类型是对支持IDispatch接口的对象的引用(请参阅)。这就是允许您在VB和VBScript中进行后期绑定的原因。用VB6编写的所有对象都自动实现从IDispatch继承的接口。这称为双接口,因为它支持早期和晚期绑定

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


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

我意识到VB6是一种基于COM的语言,不基于.NET framewwork。我的问题是关于变体的。VB6变体包含一个结构,我能看到的唯一可能有用的细节是强调VB只直接支持暴露双接口的COM对象,因为它不想进入区分支持和不支持后期绑定的对象的模糊世界。另一方面,这不是一个严格的限制,因为可以通过使用SendMessage和EM_GETOLEINTERFACE以及iUnknown类型的变量来获得到独占早期绑定COM类的接口。