- Thu 21 August 2014
- misc
- Jacob Sparre Andersen
- #self-reference
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;