Declarations with New
The New statement is often used in object declarations. This gives the declaration a syntax so similar to an intrinsic variable declaration that you might be tempted to think they work the same way. You understand how this works:
Dim chunk As TChunk
chunk.Title = “Chunk-a-lunk”
Surely this must be the object equivalent:
Dim thing As New CThing
thing.Title = “Thing-a-ling”
thing.Square
Those statements seem simpler and shorter than these:
Dim thing As CThing
Set thing = New CThing
thing.Title = “Thing-a-ling”
thing.Square
You might be tempted to fall into the old C trap of assuming that the more expressions you can cram into each line of code, the faster your program will run. It just isn’t so. Whether you use Set to create the object in a separate step or whether you use New in the declaration, you’re going to end up with the same thing—an object variable that references a separate object. You can get a clue about what’s happening by stepping over these statements in the debugger. In neither case will you step on the Dim line. You can’t set a breakpoint on it, either. That’s because it’s not executed at run time. The statement reserves space for the object variable at compile time, but it doesn’t create the object.
Visual Basic intrinsic variables are always initialized to something—usually zero or empty. Object variables are initialized to Nothing. So whichever version you use, you still end up with Nothing. The difference occurs when you execute the next statement. If you declared the variable with New, Visual Basic automatically creates a CThing object for you the first time you use it. It’s as if you wrote the following code:
Dim thing As CThing
If thing Is Nothing Then Set thing = New CThing
thing.Title = “Thing-a-ling”
If thing Is Nothing Then Set thing = New CThing
thing.Square
If thing Is Nothing Then Set thing = New CThing
’ Continue like this for all properties and methods
You don’t have to write all that extra code to check for Nothing; Visual Basic writes it for you. But you do have to execute it. Why can’t the compiler see that you’ve already created the object variable after the first statement and quit checking? Because it’s a compiler. Consider this statement:
Dim thing as New CThing
If fHellFrozenOver Then thing.Title = “The latest thing”
The compiler can’t tell at compile time whether hell is frozen over. That won’t be known until run time. Thus it won’t know whether to create a new CThing object without checking. Theoretically, you could write an optimizing compiler that would analyze conditionals and eliminate redundant checks in cases where there was only one possible code path. But that compiler couldn’t work on p-code, where every statement has to stand on its own. You’re better off just using the Set statement to create the objects yourself.
Now, before you throw New out of your declarations toolbox, take a look at the results of the Performance sidebar on page 133. The real-world penalty for using New in declarations for compiled code just isn’t worth worrying about. It’s all but free.
Furthermore, using New in declarations can be a powerful way of managing memory allocation, especially with global or form-level variables. Let’s say you declare this variable at the form level:
Private thing As New CThing
The thing variable is set to Nothing and no memory is allocated for the CThing object. If you follow a code path that never uses the thing variable, it never gets created. You pay no penalty (except for one object variable) for the unused object. But let’s say you do use the thing variable at some point. It is automatically created and you can use it up. Once you’ve milked it dry, you might want to throw the worthless thing away. Since it’s declared at the form level, thing isn’t going to automatically go out of scope and destroy itself until the form is destroyed, but you can free that unused memory specifically like this:
Set thing = Nothing
As long as no other object variable has a reference to the same object, it will go away and its memory will become available for other uses. But if you later decide you need that object again, just reference it again and it will spring to life again (but without any previous state values).
This form of automatic memory management is often used with form objects, including the automatic ones used for startup forms. They’re also used in global classes, as you’ll see later.