VB6对象和数据类型

w00*_*977 6 vb6

据我所知,类Object在面向对象的编程语言中位于类层次结构的顶层,就像Java一样.我也明白你在.NET中有引用类型和值类型.我也理解基于C语言的类型定义.

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

Mar*_*haw 9

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

Bytes
0-3    VTable1 pointer
4-7    VTable2 pointer
8-11   VTable3 pointer
...
       Instance data
Run Code Online (Sandbox Code Playgroud)

VTable是一个由32位指针组成的数组,这些指针都传递给"this"实例指针.

Bytes
0-3    Func1(this, ..., ...)
4-7    Func2(this, ..., ...)
8-11   Func3(this, ..., ...)
...
Run Code Online (Sandbox Code Playgroud)

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

QueryInterface()
AddRef()
Release()
Run Code Online (Sandbox Code Playgroud)

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

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

VB'Object'类型是支持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),表示正在封装的Automation类型,后8个字节可用于包含最多8个值的类型字节,或指向另一种类型的32位指针.VB使用其内部函数以及所有必要的内存分配和解除分配,在VB类型和变体之间进行所有必要的转换.变量可以包含对COM对象的引用,方法是将指向对象的指针复制到Variant中,并调用对象的AddRef()方法.


RBa*_*ung 5

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

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

其次,你的链接指向的实际上是VB6内置的.即便如此,它称之为"物体".他们的术语邋.

第三,也许最重要的是,在VB6中,一切都不是Object,而Objects甚至不是数据类型的默认或主导类别.什么是类似.Net的价值类型,但更少(大多数甚至没有运行时类型容器,只有内存中的地址).

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

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

Variant本身会跟踪其内容的数据类型,并使访问它的VB代码以不同/适当的方式运行(一种原始的多态).

如果这听起来像它的kludgy并且是很多开销,那么它就是.但当时,当您需要处理"任何数据类型"时,它是最佳可用解决方案.