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,fa2cc518ef3b992c X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: tagged types extensions - language design question Date: 2000/01/31 Message-ID: #1/1 X-Deja-AN: 579867413 Content-transfer-encoding: 7bit References: Content-Type: text/plain; charset="US-ASCII" X-ELN-Date: Mon Jan 31 04:55:09 2000 X-Complaints-To: abuse@earthlink.net X-Trace: newsread1.prod.itd.earthlink.net 949323309 38.26.88.104 (Mon, 31 Jan 2000 04:55:09 PST) Organization: EarthLink Network, Inc. Mime-version: 1.0 NNTP-Posting-Date: Mon, 31 Jan 2000 04:55:09 PST Newsgroups: comp.lang.ada Date: 2000-01-31T00:00:00+00:00 List-Id: In article , "Vladimir Olensky" wrote: > Yes, as a matter of fact this is not a big deal. > Actually everything needed could be declared in one package. > One need just to remember the right sequence - first to declare > abstract public extension of the root type, then it's abstract private > extension and then concrete final extensions (in my case two of them). 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. If you have a "by-reference" abstraction, that is, an abstraction designated by a pointer, then there's an idiom for that too. (You need to put objects on the heap when you have "containment by reference," instead of "containment by value," as is often the case when doing class-wide programming.) Basically, you declare the type as limited and indefinite, and declare all primitive operations with access parameters: package P is type T (<>) is abstract tagged limited private; type T_Access is access all T'Class; for T_Access'Storage_Size use 0; procedure Op (O : access T); ... end P; Non-abstract types in the class declare a constructor for the type: package P.C is type NT is new T with private; function New_NT return T_Access; -- possibly NT_Access procedure Op (O : access NT); ... end P.C; That all types in the class are limited and indefinite prevents clients from declaring their own instances directly. You want to force them to use your constructor. In general, a client should never invoke an allocator ("new T") directly. Give them a constructor, and invoke the allocator internally. 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 Both of these techniques are in the patterns archive (which I'm about to do some maintenance of).