Author: david bolton
One of the worst things you can do is not call a destructor for an object. I found
this the hard way with my article on Compound Volumes. The destructor call ensured
that any new additions to the file were properly recorded. So forgetting it caused
corruption if new files were added.
Answer:
So what we want is a way to call the destructor automatically if you forget to do
it. Now I could be accused of encouraging lazy programming. So what you should do
is put a ShowMessage call saying something like “*Oi dipstick, you haven’t called a
destructor”. That way you avoid corrupting data and your mistakes are found a bit
easier.
Heres the main code to be added after the implementation section:
Note that calling TObject(Pointer).Free works for all objects. (Unless you know
better...)
1 var2 cvList: Tlist;
3 4 const5 InTidy: boolean = false;
6 7 procedure Remove(V: TCompoundVolume);
8 var9 Index: integer;
10 begin11 if InTidy then12 exit;
13 for Index := cvlist.count - 1 downto 0 do14 if cvlist[Index] = v then15 cvlist.Delete(Index);
16 end;
17 18 procedure Tidylist;
19 var20 Index: integer;
21 begin22 if InTidy then23 exit;
24 InTidy := true;
25 for Index := cvlist.count - 1 downto 0 do26 if assigned(Cvlist[Index]) then27 begin28 TObject(Cvlist[index]).Free;
29 cvlist.Delete(Index);
30 end;
31 InTidy := false;
32 end;
33 34 //In the class creator add this line 35 36 cvList.Add(Self);
37 38 //and in the destructor add this 39 40 Remove(Self);
And in your unit, add the lines or modify the Initialization/finalization sections
41 initialization42 cvlist := tlist.Create;
43 44 finalization45 TidyList;
46 cvlist.free;
If your destructor is called by you, the call to Remove will remove it from the
list. This needs a recursion check in case you forgot to call it and it tries to
call Remove while the destructor is called from TidyList. That is what the flag
InTidy guards against.
*Dipstick is a mild English term of abuse, about the same as tosspot or tosser, but not as bad as say wanker.