comp.lang.ada
 help / color / mirror / Atom feed
From: Matthew Heaney <matthew_heaney@acm.org>
Subject: Re: Destructor question
Date: 1998/12/06
Date: 1998-12-06T00:00:00+00:00	[thread overview]
Message-ID: <m3r9ud5uy8.fsf@mheaney.ni.net> (raw)
In-Reply-To: 74d0i5$itj$1@nnrp1.dejanews.com

david.c.hoos.sr@ada95.com writes:

> Here is my solution to the problem, based on Robert Eachus's post to
> this thread.
> 
> I do, however, find some points of Robert's posting at variance with
> what I was able to make work, viz.:
> 
>     1.  Robert said "Next, you need, and this need not be visible, to
>     have a two parameter version that is dispatching on Object" I do
>     not see how this can be made invisible, since it needs to be a
>     primitive operation of the type.  Perhaps someone can enlightne me
>     on this.

Primitive operations aren't necessarily declared in the public region
of the spec.  For example, in my post about the Visitor pattern, the
free operation is primitive, yet private:

package Equipment is

   pragma Pure;

   type Root_Equipment (<>) is abstract tagged limited private;

private

   type Root_Equipment is
     abstract tagged limited null record;

   procedure Do_Free
     (Equipment : access Root_Equipment);

end Equipment;


Because operation Do_Free is declared in the private region, is only
available within the subsystem of packages rooted at Equipment.

Typically, such operations are named Do_<something>, and are used to
implement public operations (primitive and class-wide).

In the visitor example, Composite_Equipment (an abstract type)
implements Do_Free by calling Do_Free on each of its items, which
dispatches according to the tag of the item.  Thus, Do_Free is a
dispatching deconstructor:


   procedure Do_Free
     (Composite : access Composite_Equipment) is

      procedure Free_Item
        (Item : access Root_Equipment'Class) is
      begin
         Do_Free (Item);  <-- !!! dispatching deconstructor
      end;

      procedure Free_Items is
        new For_Every_Item (Free_Item);

   begin

      Free_Items (Composite);

   end Do_Free;


Cabinet, a non-abstract type which derives from Composite_Equipment,
calls its parent's Do_Free (to actually delete the items), then deletes
itself:

   procedure Free
     (Cabinet : in out Cabinet_Access) is
   begin

      if Cabinet = null then
         return;
      end if;

      Do_Free (Composite_Equipment (Cabinet.all)'Access);

      Deallocate (Cabinet);

   end Free;


Free is the public operation that does deletion.  It is implemented by
calling Do_Free.

Note that this technique is slightly different from the solution
suggested by Bob Eachus.

The complete post (with compilable code) is located in the Nov 1998 link
at the ACM patterns list archive.

<http://www.acm.org/archives/patterns.html>





  reply	other threads:[~1998-12-06  0:00 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-12-02  0:00 Destructor question Rusnak
1998-12-03  0:00 ` Jeff Carter
1998-12-03  0:00   ` Rusnak
1998-12-04  0:00     ` Robert I. Eachus
1998-12-06  0:00       ` Matthew Heaney
1998-12-08  0:00         ` Robert I. Eachus
1998-12-06  0:00     ` Matthew Heaney
1998-12-07  0:00     ` Jeff Carter
1998-12-06  0:00 ` Matthew Heaney
1998-12-06  0:00 ` david.c.hoos.sr
1998-12-06  0:00   ` Matthew Heaney [this message]
1998-12-08  0:00   ` Robert I. Eachus
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox