What is the reason for not instantiating an object at the time of declaration?

后端 未结 4 745
南旧
南旧 2020-12-01 16:09

I had to delve into some VB6 code recently and I saw this pattern all over the place:

dim o as obj
set o = new obj

Why not this?

         


        
4条回答
  •  -上瘾入骨i
    2020-12-01 17:03

    This question touches on one of the many reasons that experienced programmers really dislike VB6. The New keyword changes the way the declared variable works. For instance:

    Dim MyObject As MyClass
    Set MyObject = New MyClass
    Set MyObject = Nothing
    Call MyObject.MyMethod()
    

    ... throws a runtime exception, while this:

    Dim MyObject As New MyClass
    Set MyObject = Nothing
    Call MyObject.MyMethod()
    

    ... does not. Personally, if I go to the effort of setting a variable to Nothing, then referencing it again is almost certainly an error and I'd really like the program to crash, thank you very much. It's particularly important in the case where the class allocates resources in the initializer (constructor) and needs to get rid of those in the destructor. It's reasonably easy to write code that incorrectly references variable set to Nothing, perhaps when you want to check a result value or something. Doing this could cause the class to be instantiated again, grabbing all the unnecessary resources.

    The reason for this weird behavior is so that VB6's forms (which are classes) work the way a novice would expect them to work. There's an implicitly declared global variable with the same name and type as each defined form, so:

    Call frmMain.Show
    

    ... doesn't crash. This is the same behavior. It's really doing:

    If frmMain Is Nothing Then
        Set frmMain = New frmMain
    End If
    Call frmMain.Show
    

    This very much goes against what we're used to in other object oriented languages, so, in my opinion it's a bad idea. It's trying to hide the fact that MyObject is a reference type, and yet, when you write something like this (without using Set):

    MyObject = New MyClass
    

    ... then you get a runtime exception instead of a compiler error because you didn't use the Set command. The compiler knows it's a reference type... why do I have to use Set, and even if I do, why not tell me about it sooner?

    At any rate, to answer your question, you rarely want the behavior implied by using the Dim ... New syntax because you want to control the construction and destruction of objects. In fact, the only time it would ever make sense is in the construction of global singleton objects (such as frmMain above) where you just want the syntactic sugar. I would argue that global singletons are a bad idea anyway, so if I could turn off the ability to use the Dim ... New syntax, I would.

提交回复
热议问题