读书人

关于vb的public变量与property的有关问

发布时间: 2012-04-17 15:06:33 作者: rapoo

关于vb的public变量与property的问题
//发现每加一个Public普通变量,偏移量就会加8

定义一个Public普通变量,VB会自动为你实现PROPERTY GET,PROPERTY PUT,即:
public x as long后
vb会处理为:
Public Property Get x() As Long

End Property

Public Property Let x(ByVal vNewValue As Long)

End Property

这一点你用oleview看一下就知道了

我想知道这个是怎么看的,打开oleview之后..?

哪位老大给解释下,不胜感激!

[解决办法]
我基础不好,我来顶贴蹭分..
定义一个Public普通变量,VB会自动为你实现PROPERTY GET,PROPERTY PUT,这个我知道,看过相关文章,有人可能会问:那为什么要用PROPERTY GET,PROPERTY PUT,直接public变量不是很简单? 我自己的理解就是可以在其中定义一些规则和业务逻辑等等...
不会你的问题,学习下...

[解决办法]
打开oleview之后,单击 File-> View TypeLib 选择你生成那个activex dll文件。

在打开的ITypeLib Viewer窗口里你就能看到你dll中所有类的信息

比如我在dll里建了一个叫CSplash的公共类,类中的代码为:

VB code
Public x As LongPublic Sub ShowSplash()End SubPublic Sub Terminate()End Sub
[解决办法]
嘿,这么多分,俺也来蹭一下。
实际上,这是由于VB屏蔽了太多底层的东西所引起的。COM是用IDL来进行描述的,在VB中,也称为ODL,其实质是IDL在VB中本地化的子类。
在IDL中,只有接口和类工厂,而接口中只有方法和属性,并没有什么公共变量。VB里的类,其实质就是一个COM接口,而类中的公共变量,其实质也是属性,最终会被编译器自动转换为了Property。
这些东西都可以通过oleview来查看。
[解决办法]
我基础更差,我也来蹭分:我认为VB中的属性就是属性的读取和写入的问题,你自定义一个类,它的属性不是一个Public声明的变量,就是一个property定义的过程,因此,我认为Public普通变量,在VB内部就是处理成了一个属性过程
[解决办法]

我也蹭个分。。。

属性的实现方法其实就是函数,也有直接以值存放的方法

类里面的函数/属性要在vtable的结构中体现出来的,这样类外调用该类才能找到相对应的函数

一般情况下是iunknow接口实现查询id,根据id返回函数地址

一个函数属性占用4字节空间存储地址,get/let是两个属性函数,就要 +8 的空间存储地址

odl  idl 都是对象描述语言,本质上没有太多的区别
一些可以做为区别的东西是,odl是原始版本的对象描述语言,他的形式很象c++,但并非c++
而idl是ms后来出的odl加强版,代码形式十分接近c++,但ms说,他一样不是c++
[解决办法]
来蹭分了了哈~
顶起
[解决办法]
飘过

顺便问AC。你干嘛要问这个问题?
[解决办法]
我看过Matthew Curland编著的《高级Visual Basic编程》,知道VB6的数据类型全都是基于COM的数据类型,但没知道那么多,书没看完。IUnknown、IDispatch都是这里讲的内容。Public变量的确有这个问题,不能定义太多,但有时候又不能不用!
拿现在面向对象的编程技术来说,会破坏数据的隐蔽性。
[解决办法]
探讨
另外,太气人了。大家居然都知道COM。还都知道IUnknown、IDispatch等等

[解决办法]
我基础不好,纯粹来学习的


[解决办法]
学习
[解决办法]
探讨

..........

早期绑定,通过编译器支持,能够将对象中的函数地址以直接的形式表现出来
一个例子,就是
dim a as new class1
call a.方法1(参数)
......

[解决办法]
探讨
我准备根据楼主的问题写系列文章呢,内容包括变量的定义、变量的内存分配、变量地址的获得和使用。

[解决办法]
再对上面的最后一句补充说明一下。
实际上对类的公共变量使用VarPtr(m),获得的并不是变量m的本身(也就是我前面打比方所说的名称)地址,而是获得类中对应此变量的一个私有变量的幅本。当类每被实例化一次,就为在内存中产生一个数据幅本(成员函数则没有)。
先看一看一个完整的属性,代码如下:
dim m_v as long
public property get m() as long
m=m_v
end property
public property let m(byval NewVal as long)
m_v=NewVal


end property
对于这个属性,在前期绑定中,由于副本地址已确定,故使用o1.m=100这样的语句进行赋值,根本不会调用public property let m(byval NewVal as long)这个函数,而是直接执行了m_v=100,从而减少了由函数调用带来的栈平衡操作。在后期绑定中,由于不知道m_v幅本的地址,所以不能实现m_v=100这样直接赋值,而是先在函数表中查询成员函数public property let m(byval NewVal as long)地址,再调用这个地址实现对变量m_v的赋值。前面我还说过,类的成员函数地址是可以确定的,这是因为一个类只有一个成员函数表,又由于类可以被继承,这个表会在继承时被增加一些项目,所以叫它虚函数表。
综上所述,我们可以看出早期绑定为什么比后期绑定效率要高一些,也应该明白类中的公共变量与属性有什么区别了。至于我所说的变量本身地址编译时确定,在这儿一样有效。一方面对于类来说,成员变量m_v是编译时分配了空间的,而varptr(m)根本不是指向变量m,而是指向变量m运行时的一个幅本的地址,这个幅本的地址不是由类本身确定的,而是由类的调用入实现的,当对类实现早期绑定后,这个幅本也成了一个或几个变量(视实例化次数而定),会在调用者的空间里占用地址。

上述均针对进程内的类对象有效,对于需要在进程间进行调度的,还得需要进一步验证。

读书人网 >VB

热点推荐