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=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,56131a5c3acc678e X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-11-26 01:25:57 PST Path: archiver1.google.com!news2.google.com!fu-berlin.de!uni-berlin.de!tar-atanamir.cbb-automation.DE!not-for-mail From: Dmitry A. Kazakov Newsgroups: comp.lang.ada Subject: Re: Question about OO programming in Ada Date: Wed, 26 Nov 2003 10:29:20 +0100 Message-ID: <8rp8svo8qmf1b68jpuc9c2bio4ul8bbk8p@4ax.com> References: NNTP-Posting-Host: tar-atanamir.cbb-automation.de (212.79.194.116) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1069838756 64417936 212.79.194.116 ([77047]) X-Newsreader: Forte Agent 1.8/32.548 Xref: archiver1.google.com comp.lang.ada:2954 Date: 2003-11-26T10:29:20+01:00 List-Id: On Wed, 26 Nov 2003 01:34:04 +0100, "Ekkehard Morgenstern" wrote: >How do I assign an object of type T to an access to T'Class? Use 'Access and 'Unchecked_Access attributes to get a pointer (access type object) to some existing [aliased!] object. Conversion from specific to class-wide pointer is implicit. It is also true when you use "new" to create a new object. The result is a specific pointer which can be implicitly converted to a class-wide one. >Like, I have a node class, > > type Node; > type Node_Ptr is access Node'Class; > > type Node is tagged > record > Succ : Node_Ptr; > Pred : Node_Ptr; > end record; > >and a method like > > procedure NextNode( Node_Obj : in out Node'Class ); > >how do I assign a Node to a Node_Ptr? You can, but it is a bad design. Though "in out" means that you can modify object, still it is not allowed to change the object's tag. So if the next node has another specific type than one of Node_Obj you will get Constraint_Error: procedure Next_Node (Node_Obj : in out Node'Class) is begin Node_Obj := Node_Obj.Succ.all; -- May raise Constraint_Error on many occasions! end Next_Node; So at least it should be: function Next_Node (Node_Obj : in Node'Class) return Node'Class is begin return Node_Obj.Succ.all; -- Also raises Constraint_Error, -- but only if Node_Obj.Succ is null end Next_Node; Then note that this function would copy the node. Very likely it is not what you want. Probably, nodes cannot be copied at all so: type Node is tagged limited record ... This would prevent any attempt to assign a node. [You still may have functions returning limited objects, their results cannot be assigned but can be renamed.] Even more, probably a node should remove itself from the graph upon destruction. Then: type Node is new Ada.Finalization.Limited_Controlled with record ... Probably there should be no empty nodes, and thus: type Node is abstract new Ada.Finalization.Limited_Controlled with record ... Anyway the right thing likely is: function Next_Node (Node_Obj : in Node'Class) return Node_Ptr is begin return Node_Obj.Succ; end Next_Node; Note that Randy's point is still valid. Pointers are bad, though inevitable on some lower levels of abstraction as we see it here. Should you change the abstraction and switch from Get_Next to, say, an node navigatior, which would call a dispatching procedure that does something with a node ... you could get rid of pointers. >How can I exploit Ada's storage management to the max? > >Especially when I have things like Lists and Nodes, Queues etc. or other >container classes? You can allocate items, nodes in your own storage pools. If you know something special about the way items get allocated / deallocated, you may implement a more efficient memory allocation strategy than the default one. For example, in my project I have dynamically created / removed constraints, about which I know that they are always allocated in LIFO. I cannot use the program stack (declare-begin-end block) for them. So I chose to implement a stack memory pool and use it to keep the constraining objects there. -- Regards, Dmitry Kazakov http://www.dmitry-kazakov.de