Self-referencing Objects


One may in some cases want an object to contain a reference ('Access) to itself.

The package Self_Referencing_Objects shows how one can implement (consistently) self-referencing objects using limited records and discriminants.

type Instance is limited private;
...
type Holder (Reference : access Instance) is limited null record;
type Instance is limited
   record
      Self : Holder (Instance'Access);
      ...
   end record;

Notice how Self.Reference is initialised with the access value of the containing Instance object using Instance'Access.

The first declaration of type Instance could also be a forward type declaration:

type Instance;

Full example

We make a type, which can be passed as an in parameter, even if it is going to be modified in the receiving subprogram.

Specification:

package Self_Referencing_Objects is
   type Instance is limited private;
   procedure Increment (Counter : in     Instance);
private
   type Holder (Reference : access Instance) is limited null record;
   type Instance is limited
      record
         Self    : Holder (Instance'Access);
         Counter : Natural := 0;
      end record;
end Self_Referencing_Objects;

Body:

package body Self_Referencing_Objects is
   procedure Increment (Counter : in     Instance) is
      --  Notice that Counter is 'in', but still can be modified.
   begin
      Counter.Self.Reference.Counter := Counter.Counter + 1;
   end Increment;
end Self_Referencing_Objects;