From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,3dbb4bb0201c39eb X-Google-Attributes: gid103376,public From: Matthew Heaney Subject: Re: Destructor question Date: 1998/12/06 Message-ID: #1/1 X-Deja-AN: 419262186 Sender: matt@mheaney.ni.net References: <3665B85D.A2663591@nowhere.com> <74d0i5$itj$1@nnrp1.dejanews.com> NNTP-Posting-Date: Sun, 06 Dec 1998 04:13:25 PDT Newsgroups: comp.lang.ada Date: 1998-12-06T00:00:00+00:00 List-Id: 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_, 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.