标题: [技术讨论] 我对VBS函数与过程的理解,不对之处请指证 [打印本页]
作者: yiwuyun 时间: 2014-12-31 19:31 标题: 我对VBS函数与过程的理解,不对之处请指证
- Option Explicit
- dim obj
- '只有0个或一个参数时,不论怎样调用都正确。但有两个或以上参数时,加()必须使用call。不使用call,必须去掉()。参数
- '之间都用逗号(,)分隔。---过程调用的用法。
- call Main("1","2")
- 'Main "1","2"
- Sub Main(first,second)
- For Each obj in ShellObject(1,2).Environment("system")
- WScript.Echo(""+first+":"+second+":"+obj)
- Exit For
- Next
- End Sub
-
- '函数有三种调用方式。一种是通常用的赋值。一种是过程调用方式,就如上面的Main过程调用一样。第三种如上面,它不赋值,但要用值。
- '第一种要保留值,如果值是对象,要用Set obj=Nothing释放;第二种不返回值。第三种不保留值,如果是对象,不需要释放。
- Function ShellObject(first,second)
- Set ShellObject= WScript.CreateObject("Wscript.Shell")
- End Function
复制代码
请指出不正确之处,如果都对,那不是过程纯粹可以不要了。
作者: g495326 时间: 2015-1-1 12:41
本帖最后由 g495326 于 2015-1-1 13:33 编辑
回复 1# yiwuyun
1.函数和过程的调用方式如下:
━┉┉┉┉┉┉┉∞┉┉┉┉┉┉┉┉∞┉┉┉┉┉┉┉━
2.对象的返回可以用你说的那种方式,但是会产生2次对象复制操作,浪费时间,我认为最好的方式为在以引用的方式在参数中返回。
3.关于上图错误的调用方式,比如fun(argument, argument)的方式调用并不用产生错误,具体的表现如下
━┉┉┉┉┉┉┉∞┉┉┉┉┉┉┉┉∞┉┉┉┉┉┉┉━
4.使用function完全可以在功能上替换sub。这是没错的,开销方面就不是很清楚了。
作者: yiwuyun 时间: 2015-1-1 13:16
不错,没想到函数和过程对引用有影响。但是对象和非对象的返回好像有点不同吧,对象的返回好像只返回引用吧。非对象的返回才会赋值吧。要不然,对象的赋值何必多此一举,加个Set.我是这样理解的,不晓得对不对。
作者: g495326 时间: 2015-1-1 13:29
回复 3# yiwuyun
在函数中创建的对象在函数退出后,其对象已经被销毁,如果不发生复制,函数返回的对象将无法调用。
作者: yiwuyun 时间: 2015-1-1 13:38
我试了一下,不是是否加括号的问题,是你是用函数调用还是过程调用的方式,如果是过程调用,引用会起作用,如果是函数调用,就会传值。如果把这一句AppendSuffix(strWord),改成call AppendSuffix(strWord),这时就和AppendSuffix strWord一样了。
作者: yiwuyun 时间: 2015-1-1 13:45
回复 4# g495326
不是说,对象的引用为0时,对象才会消毁吗。如果有引用存在,对象是不会自行消毁的。
作者: g495326 时间: 2015-1-1 14:04
回复 5# yiwuyun
关于这一点,我是说明的是错误的调用方法产生的二义性,而不是正确的调用方法。
作者: g495326 时间: 2015-1-1 14:12
回复 6# yiwuyun
这是没错,关键对象创建的位置决定了其生命周期,而不是是否为0,在C++中如果一个对象销毁,指向该对象的指针就变成了垂悬指针,会导致内存泄露。
在返回对象时,假设为返回引用,这在C++中函数内创建的对象会延迟销毁,但这种方法被认为不可取(这句话不是我说的)
函数作为独立代码块应做到与外部无关性。
作者: yiwuyun 时间: 2015-1-1 14:24
回复 8# g495326
我们调用的对象都是别人用某种语言写好了的,如果内存泄露,也是那个组件有问题吧。如果在VBS中出现内存泄露,那是没有使用Set obj=Nothing的原因。我现在还不能确信的是这一句会不会出现内存泄露:For Each obj in ShellObject(1,2).Environment("System")。我在想既然VBS允许这种写法,那它应该会自行消毁对象吧。只是没有确切的证据表明这一点。一般在VBS退出之后,即使没有Set obj=Nothing,对象也会消毁吧。我想内存泄露只是针对大的VBS而言吧。那些VBS会一直在内存中运行,它建立的对象又很多,如果不消毁它建立的对象,内存就会越来越小,最后导致系统崩溃。
作者: g495326 时间: 2015-1-1 14:34
回复 9# yiwuyun
关于这种方式返回对象是否会发生对象复制,或者使用了对象延迟销毁对于简短的vbs确实无关紧要。
如果您知道win api函数如何返回,我想您应该懂得我的意思。
虽然我认为这是不好方法,但这种方法确实可以实现对象的返回。
作者: yiwuyun 时间: 2015-1-1 17:25
我认为VBS是不会自己创建对象的。因此根本不存在对象复制的问题,对象都是COM+自己创建的,对象的消毁也都是COM+自己完成的。VBS和COM+之间就是客户和服务器之间的关系。VBS告诉COM+我要用一个对象,你给我建一个,然后COM+把这个对象的引用,其实也就一个地址,告诉VBS,VBS把这个地址赋给自己空间中的变量。如果手动Set obj=Nothing,就是在告诉VBS,我不要这个引用了,VBS就告诉COM+,你把引用计数减1吧。com+如果侦测到自己某个对象的引用计数为0了,就会自己消毁这个对象。因此当VBS完全退出的时候,它会告诉相应的COM+对象把所有的引用计数减下去。这就是我说的你不手动Set obj=Nothing,对象还是会消毁。但是如果对大型的长时期(比如一年)运行很多对象数量的VBS来说,你如果不手动消毁,就叫内存泄露了。VBS就是一个解释器,或者是一个中间人,代理人。
作者: g495326 时间: 2015-1-1 19:51
回复 11# yiwuyun
com是类的封装,以dll形式存在的动态链接库文件,而不是什么对象管理器,对于您的理解不敢苟同。
不知您学习vbs多久了,希望能交个朋友。
作者: yiwuyun 时间: 2015-1-2 09:43
VBS也有自己的类对象,那些类对象就是由VBS创建的,但用CreateObject()方法创建的对象,就是由COM+创建的,如果你看过VC++ COM/COM+编程应该就能明白了。另外C++是不存在延迟消毁对象一说的,C++都是手动消毁对象,只有JAVA才延迟消毁对象,JAVA的程序员从来都是只建对象,不消毁对象,对象是由JAVA垃圾清理器自动完成的。所以JAVA从来不会出现内存泄露。内存泄露是C/C++才会出现的。这只是我个人的理解。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |