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,FREEMAIL_FROM, INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,fa2cc518ef3b992c X-Google-Attributes: gid103376,public From: "Vladimir Olensky" Subject: Re: tagged types extensions - language design question Date: 2000/01/31 Message-ID: #1/1 X-Deja-AN: 579948073 References: Organization: Posted via Supernews, http://www.supernews.com X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Newsgroups: comp.lang.ada X-Complaints-To: newsabuse@supernews.com Date: 2000-01-31T00:00:00+00:00 List-Id: Matthew Heaney wrote in message ... >In article , "Vladimir Olensky" > wrote: > >Yes, you have to declare the public part of abstraction first. > >> Very similar to the case when one wants to declare deallocation >> procedure for some private type in the same package where this >> private type is declared. Here right sequence is also very important >> and might be even less obvious for those who encounter that need >> for the first time. <...> >The other issue is how to reclaim instances. You can either provide: > >1) a classwide Free operation (declared in the root package, and >implemented by calling an instantiation of Unchecked_Deallocation, or by >calling a private dispatching deconstructor) > >2) instead of using an access type, use a smart pointer, and let >deallocation be automatically As a matter of fact I am using both techniques when appropriate. For private types I frequently use inlined public classwide Free procedure that calls private Free_Obj classwide procedure: package P is type Root is abstract new Limited_Controlled with private; type Root_Ref is access all Root'Class; procedure Free (obj_Ref : in out Root_Ref); pragma Inline (Free); private type Root is abstract new Limited_Controlled with record Ref_Count : Integer := 0; -- for "smart pointer" when it is used; ; record; procedure Free_Obj is new Ada.Unchecked_Deallocation ( Root'Class, Root_Ref ); end P; package body P is procedure Free (obj_Ref : in out T_Ref) is Free_Obj (obj_Ref); end Free; end P; That's it. It works for any descendants of the root class. >In general, a client should never invoke an allocator ("new T") >directly. Give them a constructor, and invoke the allocator internally. Constructor for any descendants of Controlled type is it's Initialize procedure. With controlled types one does not need to create special public constructor for the derived class. Everything is done automatically by the Initialize. Yes, if one does not want to use controlled type then one may want to provide his/her own public constructor. Regards, Vladimir Olensky