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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bd1d347880390e54 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-16 13:28:11 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!headwall.stanford.edu!fu-berlin.de!uni-berlin.de!82-43-33-75.cable.ubr01.croy.blueyonder.co.UK!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: Type conversions on pool-specific access types Date: Thu, 16 Oct 2003 21:28:07 +0100 Message-ID: References: <7kukov45dif9p7u2ohu6ml29mu9cgu621o@4ax.com> Reply-To: "Nick Roberts" NNTP-Posting-Host: 82-43-33-75.cable.ubr01.croy.blueyonder.co.uk (82.43.33.75) X-Trace: news.uni-berlin.de 1066336088 25881042 82.43.33.75 (16 [25716]) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4807.1700 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700 Xref: archiver1.google.com comp.lang.ada:1017 Date: 2003-10-16T21:28:07+01:00 List-Id: "Dmitry A. Kazakov" wrote in message news:g5ksovoq9nkg0tb53rgrn40vjjl7l5cqkb@4ax.com... > > ... > > declare > > Ptr : Base_Ptr := new Derived; > > begin > > Foo(Ptr); > > Yes, in this case. But consider specialized containers of > Derived descendants: > > procedure Derived_Specific (X : Derived); > type Array_Of_Derived is array (...) of Derived_Ptr; > > Now you can call Derived_Specific on any element of > Array_Of_Derived without an explicit type conversion. > It is also type safe. If I have only Base_Ptr, I lose that > advantage and forced to always work in the terms of > the base type and what is worse, to make casts. In this situation, I suggest you declare: type Derived_Ptr is access Derived'Class; type Array_Of_Derived is array (...) of Derived_Ptr; exactly as you suggest, so you can call: Derived_Specific( Array_Of_Derived(...).all ); If you now wish to call Foo for an object designated by a component of the Array_Of_Derived array, you do indeed need to do a conversion. I think this can be adequately achieved in Ada 95 by the use of an intermediate general access type: type General_Base_Ptr is access all Base'Class; procedure Foo (Object: in General_Base_Ptr); Now we can call Foo for objects of type Base_Ptr or Derived_Ptr: X: Base_Ptr; ... Foo( General_Base_Ptr(X) ); Foo( General_Base_Ptr(Array_Of_Derived(...)) ); If you do not need to be able to pass null values, an alternative is to make the parameter to Foo of an anonymous access type: procedure Foo (Object: access Base'Class); Then the conversions are implicit: Foo( X ); Foo( Array_Of_Derived(...) ); I recognise that this is not the neatest solution imaginable, but I think it works, and will be reasonably efficient. It has the possible advantage that you could choose to have Base_Ptr and Derived_Ptr objects stored in different pools (and the new Foo will still work, since it accepts a general access type). > [Finalize should not deallocate Object] > Theoretically true, but practically, consider a situation > when objects have to be always allocated in a specific > pool. For example, on a user-defined stack. Further each > object has to remove itself from some list. It is made > upon finalization. The problem is that in this case you > cannot use the advantages of thin pool-specific pointers. I repeat that a controlled object should not attempt to deallocate itself during its own finalisation. In order to cause the deallocation of an object, an instance of Unchecked_Deallocation should be called at the appropriate time, which can be expected to: (1) call Finalize for the object; (2) call Deallocate for the object's pool. One way to obtain the calling of an instance of Unchecked_Deallocation for all the objects in a linked list is to declare a controlled type which contains a pointer to one of the objects in the list, and to implement the Finalize procedure of this type to chase down the list deallocating objects as it goes. For example: type My_Object; type My_Object_Ptr is access My_Object; type My_Object is new Ada.Finalization.Controlled with record Next: My_Object_Ptr; ... end record; type My_Object_List is new Ada.Finalization.Controlled with record First: My_Object_Ptr; ... end record; procedure Free is new Ada.Unchecked_Deallocation(My_Object,My_Object_Ptr); procedure Finalize (List: in out My_Object_List) is Obj, Tmp: My_Object_Ptr; begin Obj := List.First; List.First := null; while Obj /= null loop Tmp := Obj; Obj := Obj.Next; Free(Tmp); -- will call member's Finalize and its pool's Deallocate end loop; end Finalize; procedure Do_Something_Using_a_List is L: My_Object_List; begin ... -- add members to the list L end; -- L will be finalised here, which will cause the whole list to be finalised and freed properly Hope this is helpful! -- Regards, Nick Roberts