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: eachus@spectre.mitre.org (Robert I. Eachus) Subject: Re: Destructor question Date: 1998/12/04 Message-ID: #1/1 X-Deja-AN: 418783412 References: <3665B85D.A2663591@nowhere.com> <3666BACC.99E6BB06@spam.innocon.com> <3666F7F1.9B107D38@nowhere.com> Organization: The Mitre Corp., Bedford, MA. Newsgroups: comp.lang.ada Date: 1998-12-04T00:00:00+00:00 List-Id: In article <3666F7F1.9B107D38@nowhere.com> Rusnak writes: > Given a type Instance which is an abstract tagged record and a type > Object which is of type access all Instance and a type Class_Object which > is of type access all Instance'Class, > I would like to define a procedure: > procedure Deallocate(The_Object : in out Object) is abstract; > which is dispatching. The compiler certainly lets me declare such a > procedure, but I can never use it, since it cannot accept a parameter of > type Class_Object to get it to dispatch. Another solution is possible, but > the above solution (if "implementable") would be the cleanest and least > intriusive way to go. 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); 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); -- you may not need this if using Controlled Free(The_Access); end Deallocate; -- There is a LOT of magic going on here. Since this procedure is a -- primitive operation of type Object, it will be derived when you -- create subclasses of Object. Note that the parameter -- "The_Object" is never used, it is just there to get the -- dispatching. The instance(s) of Unchecked_Deallocation are not -- class-wide, so they work. The call to Deallocate is not -- dispatching, but that's all right, the dispatching has already -- been done. The only use of 'Class is in the declaration of -- Object_Class, but that is fine, the call to the two parameter -- Deallocate from the one parameter version dispatches because -- the type of The_Access.all is class-wide. -- Finally, you only need to declare the non-class-wide single -- parameter version of Deallocate, if you are not using Finalize. > 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. Why doesn't explicit casting seem to work? Read about "view conversions" to see that type conversions can do exactly what you want. But in general you shouldn't need to do such "casting" to call the operation on the parent type. Just make the type extensions Controlled instead of (or in addition to) the entire class when you need to do something then call the Adjust, Initialize, or Finalize for the parent. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...