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: 419379843 Sender: matt@mheaney.ni.net References: <3665B85D.A2663591@nowhere.com> <3666BACC.99E6BB06@spam.innocon.com> <3666F7F1.9B107D38@nowhere.com> NNTP-Posting-Date: Sun, 06 Dec 1998 11:52:09 PDT Newsgroups: comp.lang.ada Date: 1998-12-06T00:00:00+00:00 List-Id: eachus@spectre.mitre.org (Robert I. Eachus) writes: > Did you get my e-mail note on this? Anyway what you have do to > is to have an operation for the "root" type that takes the access type > as a parameter: > > procedure Deallocate(The_Access : in out Object_Class); > > Next, you need, and this need not be visible, to have a two > parameter version that is dispatching on Object: > > procedure Deallocate(The_Access : in out Object_Class; > The_Object : in Object); An alternative implementation uses a (private) subprogram that takes an access parameter: procedure Do_Deallocate (The_Object : access Object); This of course dispatches on the tag of The_Object. It more-or-less combines the two parameters of Bob's solution into one parameter. > > The bodies are fairly straightforward: > > > procedure Deallocate(The_Access : in out Object_Class) is > begin Deallocate(The_Access, The_Access.all); end Deallocate; > -- This dispatches on the second operand. > > procedure Deallocate(The_Access : in out Object_Class; > The_Object : in Object) is > function Free is new Unchecked_Deallocation(Object, Object_Class); > begin > Deallocate(The_Access.all); -- may not need this if using Controlled > Free(The_Access); > end Deallocate; The bodies of the alternative implementation are: procedure Deallocate (The_Access : in out Object_Class) is begin if The_Access /= null then Do_Deallocate (The_Access); The_Access := null; end if; end Deallocate; procedure Do_Deallocate (The_Object : access Object) is OA : Object_Access := Object_Access (The_Object); begin Free (OA); end; where type Object_Access is an access type that designates the specific type Object. Analogous implementations would be required for each type in the hierarchy. (I prefer to instantiate Unchecked_Deallocation using a specific type, rather than a class-wide one.) A complete example using this technique may be found at the patterns archive at the ACM: Look under month Nov 1998, and the post labeled "No subject." It discusses an implementation of the Visitor pattern that uses the memory management technique described above. >From the original post (not from Bob Eachus): > > On another note, if i override a proceudre in a derived class, how can I > > "chain" it to its super class (i.e., call within the procedure the super > > class procedure which it overrides)? I could certainly see the use in > > chaining the Initialize procedure of the Controlled class mentioned > > above. Explicit casting doesn't seem to work, and casting is not a very > > desirable solution anyway. Sometimes you need to cast. Downcasts from a class-wide type to a specific one are safe.