Title: Using class methods to detect Memory-Leaks
Question: When you dinamically create objects at runtime, you need to check that you free those objects too.
Class methods can help in the process
Answer:
Class Methods aply to the class level, in other words you dont need an instance to call the method
I wish we could define class objects as well, but they doesnt exist in Object Pascal, so we will do a trick, we are going to define a variable in the implementation section of the unit, this variable will hold the number of instances the class will have in a moment in time. Object Oriented purist might claim about it, but it works, nobody is perfect (not even Delphi!).
For example say you need to create instances of a class named TFoo, so you create the following Unit.
We will define two class procedures: AddInstance(to increse the counter of instances) and ReleaseInstance(to decrese the number of instances), these are called in the constructor and the destructor acordingly. Finally we define a class function NumOfInstances which returns the actual number of instances.
Add a Initilialization and a Finalization section to the Unit, in the Finalization section ask if the number of instances is 0, if this is the case
you known that you didint destroy all the objects that you created.
unit U_Foo;
interface
uses
Classes, Windows, SysUtils;
type
TFoo = class
private
class procedure AddInstance;
class procedure ReleaseInstance;
public
constructor Create;
destructor Destroy;override;
class function NumOfInstances: Integer;
end;
implementation
var
TFoo_Instances: Integer = 0;
{ TFoo }
class procedure TFoo.AddInstance;
begin
Inc(TFoo_Instances);
end;//end of TFoo.AddInstance
//MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMMWMWMWMWMWMWMWMWMWMWM
constructor TFoo.Create;
begin
AddInstance;
end;//end of TFoo.Create
//MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMMWMWMWMWMWMWMWMWMWMWM
destructor TFoo.Destroy;
begin
ReleaseInstance;
inherited;
end;//end of TFoo.Destroy
//MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMMWMWMWMWMWMWMWMWMWMWM
class function TFoo.NumOfInstances: Integer;
begin
Result := TFoo_Instances;
end;//end of TFoo.NumOfInstances
//MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMMWMWMWMWMWMWMWMWMWMWM
class procedure TFoo.ReleaseInstance;
begin
Dec(TFoo_Instances);
end;//end of TFoo.ReleaseInstance
//MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMMWMWMWMWMWMWMWMWMWMWM
initialization
finalization
if TFoo_Instances 0 then
MessageBox(0,
PChar(Format('%d instances of TFoo active', [TFoo_Instances])),
'Warning', MB_OK or MB_ICONWARNING);
end.