Check free object instance

Felipe Godinho

I have the following class structure.

TObjectA = class
    ...
end;

TObjectB = class
    private
        FDependencyObjectA
    public
        constructor Create(const DependencyA: TObjectA);
        destructor Destroy; override;
end;

{ TObjectB }

constructor TObjectB.Create(const DependencyA: TObjectA);
begin
    FDependencyObjectA := DependencyA;
end;

destructor TObjectB.Destroy;
begin
  FDependencyObjectA.Free;
  FDependencyObjectA := nil; 
  inherited;
end;

I'm trying to find a solution to work with these two use cases.

// Use cases

// First case 
// Works with Free on Destroyer
// Does not work without Free on Destroyer
procedure TForm1.Button1Click(Sender: TObject);
var
 ObjectB: TObjectB;
begin
   ObjectB := TObjectB.Create(TObjectA.Create);
   try
       ...
   finally
       ObjectB.Free; 
   end;
end;


// Second case
// Does not work with Free on Destroyer
// Works without Free on Destroyer
procedure TForm1.Button1Click(Sender: TObject);
var
 ObjectA: TObjectA;
 ObjectB: TObjectB;
begin
   ObjectA := TObjectA.Create;
   ObjectB := TObjectB.Create(ObjectA);
   try
       ...
   finally
       // Depending on the implementation of the Destroyer or the this finally
       // Can raise Access Violation, Invalid Pointer or Memory Leak
       ObjectB.Free; 
       ObjectA.Free;
   end;
end;

One solution would be to verify that ObjectA has already been free of memory. But I do not know a check only when the object is free, I know checks of when the object is null.

// Third case (Trying for a solution)
procedure TForm1.Button1Click(Sender: TObject);
var
 ObjectA: TObjectA;
 ObjectB: TObjectB;
begin
   ObjectA := TObjectA.Create;
   ObjectB := TObjectB.Create(ObjectA);
   try
       ...
   finally
       ObjectB.Free;       
       // It would work fine if Assigned returned false, but always returns true
       if Assigned(ObjectA) then  // or ObjectA <> nil
         ObjectA.Free;
         // If I use just assign nil instead of Free, compile throws a hint
         // ObjectA := nil;
         // H2077 Value assigned to 'Your_Variable' never used
   end;
end;

Another solution would be to inject the dependency using the reserved word var. But I want to evaluate other possibilities first.

In Delphi is there any way to check if the object is just free and not only nil?

Or is there any workaround to work with the first two use cases, without Access Violation, Invalid Pointer, Memory Leak or Compile Hints errors?

I did not just want to adopt just one use case, or have to keep checking the object's Destroyer to know how to implement a new function / procedure. This is bad for day-to-day implementations, or for when a new developer gets into the project. We would have to explain all these little rules and also be constantly reviewing whether the implementations are correct.

Edit:

I know that Delphi has ARC for Interfaces, but not all objects will implement an interface.

For hints there is the {$ Hints Off} compilation directive, but in any case adding the directive is not very viable.

David Heffernan

The correct code is this:

ObjectA := TObjectA.Create;
ObjectB := TObjectB.Create(ObjectA);
try
  ...
finally
  ObjectB.Free;       
end;

ObjectB takes ownership of ObjectA and it is therefore its job to destroy it. The calling code has passed on that responsibility and so has nothing more to do.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Check ArrayList for instance of object

Check if a object is a instance of a class (but not a instance of its subclass)

check in php if a object is a instance of a class but not a instance of a subclass

How to check if an object is of instance `Type`?

Check if method already is in instance in object?

How to check if an object is an instance of a namedtuple?

Check if object is a 'direct instance' of a class

Check if some object is instance of some class in a list

Check if object is instance of any 'number' class?

How to check if array contains instance of an object in Javascript?

JavaScript check if object is an instance of current class

Check if an object is instance of List of given class name

Check if Object is instance of String, HashMap, or HashMap[ ]

Check that a variable is an instance of a Class Object in WooCommerce

Check if Calling Object is Instance of Child Class

Check that object is not instance of any class in typescript

Check if Object fields already exists in another instance

In Node, how to check that a particular object is an instance of ChildProcess

Check whether Swift object is an instance of a given metatype

In scala, is there any way to check if an instance is a singleton object or not?

How to check that object is instance of generic in Haxe

Jest and Typescript: Unable to check if object is instance of class

Check if object created with Object.create is instance of original object

Check if object is Array of instance of specific object in Node.JS

Proper way to check type when object might be an object() instance

Applicative instance for free monad

MonadError instance for a Free Monad

Check if Object is an instance of a class from a list of classes and cast

How to check if an object is an instance of a template class in C++?