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,8ed693b245ee5483 X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: hash tables and class-wide types as fields in a record Date: 2000/02/02 Message-ID: #1/1 X-Deja-AN: 580953093 Content-transfer-encoding: 7bit References: <38986a06.0@noticias.ncsa.es> Content-Type: text/plain; charset="US-ASCII" X-ELN-Date: Wed Feb 2 12:49:35 2000 X-Complaints-To: abuse@earthlink.net X-Trace: newsread1.prod.itd.earthlink.net 949524575 38.26.192.36 (Wed, 02 Feb 2000 12:49:35 PST) Organization: EarthLink Network, Inc. Mime-version: 1.0 NNTP-Posting-Date: Wed, 02 Feb 2000 12:49:35 PST Newsgroups: comp.lang.ada Date: 2000-02-02T00:00:00+00:00 List-Id: In article <38986a06.0@noticias.ncsa.es> , "Anna Esparcia" wrote: > Now, I could declare a type pointer as follows: > > type DATA_POINTER is access all DATA_TYPE'Class; > > and an object of this type could point to any object of type DATA_TYPE or > any of its subclasses. > So, in my record above i can declare: > DATA : DATA_POINTER; > and the compiler accepts it, but when i add objects to the table the > pointers end up pointing to nothing (when the actual objects disappear). If you deallocate the object, of course you must remove that entry in the hash table. > Any ideas? Any other way of implementing the hash table? A hash table comes with GNAT. It's called gnat.htable (or something like that). Look in your ada-include directory. Another way to implement a table entry is, instead of having each node in the linked list point to an object, make the node itself an object: Here's one way: generic type Data_Type (<>) is limited private; type Data_Access is access all Data_Type; with function Get_Next (Data : Data_Type) return Data_Access is <>; with procedure Set_Next (Data : in out Data_Type; Next : in Data_Access) is <>; ... Now you can declare a data type pretty much any way you want. For example: type T; type T_Access is access all T'Class; type T is tagged record Next : T_Access; end record; procedure Set_Next (O : in out T; Next : in T_Access) is begin O.Next := Next; end; package HTable is new Generic_HTable (T, T_Access); Another way to declare the generic is to import a record whose type is known explicitly: package P is type T; type TA is access all T'Class; type T is tagged record Next : TA; end record; end P; with P; generic type T is new P.T with private; ... Now, since you know T's type, you know that it comes with a Next component. I don't really know if this is going to solve your problem, because I'm not sure why your objects are disappearing. Maybe what you need to do is declare the types together, so that each object knows that hash table it's in. When you delete the instance, the instance can remove itself from it's hash table: package P is type Hash_Table (Size : Positive) is limited private; type T (<>) is tagged limited private; type TA is access all T'Class; function New_T (Table : access Hash_Table) return TA; procedure Free (O : in out TA); ... private type TA is access all T'Class; type T (Table : access Hash_Table) is tagged limited record Next : TA; end record; type T_Array is array (Positive range <>) of TA; type Hash_Table (Size : Positive) is record Items : T_Array (1 .. Size); end record; ... end P; So when you declare an instance, you have to bind to a hash table object: Table : aliased Hash_Table; Data : TA := New_T (Table'Access); Better yet you could use a smart pointer to do the deallocation automatically, to ensure there are no dangling references. Another way to do it is statically: Table : aliased Hash_Table; Data : T (Table'Access); and the constructor for the type could enter the object in the table, and automatically remove it when it disappears.