在声明时不实例化对象的原因是什么?

Ang*_*ker 17 vb6

我最近不得不深入研究一些VB6代码,我看到了这个模式:

dim o as obj
set o = new obj
Run Code Online (Sandbox Code Playgroud)

为什么不呢?

dim o as new obj
Run Code Online (Sandbox Code Playgroud)

我记得15年前有一个很好的理由,但我不记得它现在是什么.谁还记得吗?原因仍然有效吗?

jac*_*jac 24

可能还有其他原因,但在VB6中使用New关键字时,Dim对象可能会导致意外结果,因为VB会在引用时实例化对象.

Dim objMyObject as New SomeObject

Set objMyObject = Nothing   ' the object is nothing

If objMyObject Is Nothing Then  ' referencing the object instantiates again
   MsgBox "My object is destroyed"  ' what you would probably expect
Else
   MsgBox "My object still exists"
End If
Run Code Online (Sandbox Code Playgroud)

  • 这个答案正朝着正确的方向发展,但可能不是最好的措辞?我不会使用*不可预测的*.结果完全*可预测*但对大多数开发人员来说往往是*意外*.结果还可能意味着编程错误会在运行时导致错误的错误行为,而不是一个很好的简单异常"对象变量未设置" (6认同)

Sco*_*ock 7

这个问题触及了经验丰富的程序员真正不喜欢VB6的众多原因之一.该New关键字改变声明的变量的工作方式.例如:

Dim MyObject As MyClass
Set MyObject = New MyClass
Set MyObject = Nothing
Call MyObject.MyMethod()
Run Code Online (Sandbox Code Playgroud)

...抛出运行时异常,而这:

Dim MyObject As New MyClass
Set MyObject = Nothing
Call MyObject.MyMethod()
Run Code Online (Sandbox Code Playgroud)

... 才不是.就个人而言,如果我去设置一个变量Nothing,那么再次引用它几乎肯定是一个错误,我真的很喜欢程序崩溃,非常感谢你.在类在初始化程序(构造函数)中分配资源并且需要去除析构函数中的资源的情况下,这一点尤为重要.编写错误引用变量集的代码是相当容易的Nothing,可能是在您想要检查结果值或其他内容时.这样做可能会导致类再次实例化,抓取所有不必要的资源.

这种奇怪的行为的原因是VB6的表单(它们是类)以新手期望它们工作的方式工作.有一个隐式声明的全局变量,其名称和类型与每个定义的表单相同,因此:

Call frmMain.Show
Run Code Online (Sandbox Code Playgroud)

......不会崩溃 这是相同的行为.它真的在做:

If frmMain Is Nothing Then
    Set frmMain = New frmMain
End If
Call frmMain.Show
Run Code Online (Sandbox Code Playgroud)

这非常违背我们在其他面向对象语言中习惯的东西,因此,在我看来这是一个坏主意.它试图隐藏MyObject作为引用类型的事实,然而,当你写这样的东西时(不使用Set):

MyObject = New MyClass
Run Code Online (Sandbox Code Playgroud)

...然后您得到运行时异常而不是编译器错误,因为您没有使用该Set命令.编译器知道它是一个引用类型...为什么我必须使用Set,即使我这样做,为什么不早点告诉我它?

无论如何,要回答您的问题,您很少想要使用Dim ... New语法隐含的行为,因为您想要控制对象的构造和销毁.事实上,它唯一有意义的是构建全局单例对象(frmMain如上所述),你只需要语法糖.我认为无论如何全球单身人士都是个坏主意,所以如果我能够关闭使用Dim ... New语法的能力,我会的.


Bra*_*ore 6

这是另一个警告:

For x = 1 to 100
   dim obj as new MyObject

   'Do something with obj
Next
Run Code Online (Sandbox Code Playgroud)

您可能希望新对象实例化100次,但您会发现它只是第一次实例化.很久以前这个让我措手不及.

我仍然一直使用这种表示法.只要确保你知道这种行为.