If you are doing cross border business in the European Union, then will have to deal with so called “VAT IDs”. I’ve written a small example how to validate VAT ID’s from a Delphi 2010 program. Read the rest of this entry »
Archive for July, 2010One of the most used object-oriented patterns is probably this one: foo := TFoo.create; try //do something with foo finally foo.free; end; It basically means, that if you create an instance of some class and if there is no “owner” who takes care of the new instance’s life cycle, then it is your responsibility to destroy the instance again, as soon as you are done with it. If you don’t care about freeing the objects you created, then you will get “memory leaks”, i.e. you app will use (possibly a lot) more memory as it should. The technique above is clear and simple, but what if you have more than one object that is needed in a routine? Line them up? foo := TFoo.create; bar := TBar.create; try //do something with foo and bar finally foo.free; bar.free; end; Looks good, and I see this pattern frequently – but hold on! What happens if there is an exception when TBar is created? Right, foo won’t be destroyed in that case. So maybe handle it like this then:
foo := TFoo.create;
try
bar := TBar.create;
try
//do something with foo and bar
finally
bar.free;
end;
finally
foo.free;
end;
In theory this would be the correct way, and there are a lot of examples that work like that. But look at the code – right: looks really ugly, esp. if we extend that to even more objects being created. Apart from readability there is also some performance hit: every try-frame needs some extra CPU cycles, which may sum up if your routine is time critical already. My suggestion is this one: foo := nil; bar := nil; try foo := TFoo.create; bar := TBar.create; //do something with foo and bar finally bar.free; foo.free; end; Now lets discuss some questions about this pattern: Didn’t we learn, that calls to “Create” have to be made outside the try-finally block? If TBar.create fails, what happens with its bar.free counter part? Wouldn’t it actually be executed on some not “really created” object? Why did you initialize fo and bar with NIL? If TBar.create fails with an exception, wouldn’t be there the chance that some address value would have been written to bar already – so that bar.free would be executed on some half initialized instance? |




Entries (RSS)