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.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Smart Pointers and Tagged Type Hierarchies Date: Thu, 27 Jul 2017 22:42:28 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <2017072417413775878-contact@flyx.org> <2017072721305951845-contact@flyx.org> NNTP-Posting-Host: MajGvm9MbNtGBKE7r8NgYA.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 X-Notice: Filtered by postfilter v. 0.8.2 Content-Language: en-US Xref: news.eternal-september.org comp.lang.ada:47524 Date: 2017-07-27T22:42:28+02:00 List-Id: On 2017-07-27 21:30, Felix Krause wrote: > On 2017-07-24 19:53:54 +0000, Dmitry A. Kazakov said: > >> On 2017-07-24 17:41, Felix Krause wrote: >> >>> Now I am wondering what others think of these approaches. Are there >>> alternatives? Which one would be better from a user perspective? >> >> I am using generic pointer (Handle), which can be instantiated later >> with any derived type from the base reference counting type. See >> Simple Components: >> >> http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc >> >> This is your second approach but with object pointer type passed as a >> second generic parameter. >> >> generic >> type Object_Type (<>) is abstract new Entity with private; >> type Object_Type_Ptr is access Object_Type'Class; >> package Object.Handle is >> type Handle is new Ada.Finalization.Controlled with private; >> >> Users of smart pointer need not to be generic. I don't know why you >> think it is necessary. > > Using your types, let's say I have > > type Entity_Access is access Entity'Class; > package Entity_Handle is new Object.Handle (Entity, Entity_Access); > > type A_Type is new Entity with private; > type A_Access is access A_Type'Class; > > package A_Handle is new Object.Handle (A_Type, A_Access); > > Now some subroutine wants to take an Entitiy as parameter, or more > precisely, a Handle to an Entity. If I specify this: > > procedure Do_Something (E : Entity_Handle.Handle); > > I cannot call this procedure with an A_Handle.Handle. So I'd need to do: > > generic > with package Actual_Handle is new Object.Handle (<>); > procedure Do_Something (E : Actual_Handle.Handle); > > I don't see how I can prevent this using your approach. Assuming that you are not going to derive from Entity_Handle.Handle, you have two options: 1. Provide a conversion function "-" (A : A_Handle.Handle) return Entity_Handle.Handle'Class; Then you can Do_Something (-A). 2. Provide a wrapper. Define Do_Something on A_Handle.Handle and call original the Do_Something from inside. > Another question using generics: If I do use a generic package for the > smart pointers, is there a good way to put the instance of that package > inside the package that defines the derived type? There is no good way, but it is not critical because if you are going smart pointers you also should hide objects they point to. Therefore they must go into separate packages and there will be no public cross operations in the interface packages, only factories. P.S. I don't place object types in private packages, because most likely it will leak this way or another. So I just object type packages public but mark as an implementation. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de