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 07:56:36 PST Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!hammer.uoregon.edu!skates!not-for-mail From: Stephen Leake Newsgroups: comp.lang.ada Subject: Re: Question about OO programming in Ada Date: 26 Nov 2003 10:48:41 -0500 Organization: NASA Goddard Space Flight Center (skates.gsfc.nasa.gov) Message-ID: References: NNTP-Posting-Host: shevek.gsfc.nasa.gov Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: skates.gsfc.nasa.gov 1069861988 28273 128.183.235.101 (26 Nov 2003 15:53:08 GMT) X-Complaints-To: usenet@news.gsfc.nasa.gov NNTP-Posting-Date: 26 Nov 2003 15:53:08 GMT User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 Xref: archiver1.google.com comp.lang.ada:2965 Date: 2003-11-26T15:53:08+00:00 List-Id: "Ekkehard Morgenstern" writes: > "Stephen Leake" schrieb im Newsbeitrag > news:uhe0sqfud.fsf@nasa.gov... > > > > > Do I have to use class-wide types for object-oriented programming, or > could > > > I use regular access types? > > > > Hmm. This very much depends on exactly what you mean by > > "object-oriented". > > Ok. What I'd like to know is if I can view Ada record types as classes of > objects. Yes, that's what types are. > I.e. if I declare a record, like > > type My_Type1 is > record > Field1 : Integer; > Field2: Integer; > end record; > > Can I extend the record type like > > type My_Type2 is new My_Type with > record > Field3 : Integer; > Field4 : Integer; > end record; > > such that the procedures declared to operate on type My_Type1 will operate > on the My_Type1 fields of My_Type2. Ah. That's _not_ what "class" means, but yes, Ada can do this. It's called "inheritance". You even got the syntax correct, except you need "tagged" in My_Type1. > I gathered from what I read that I need to declare My_Type1 as a > tagged type. Yes. > Now, I read that method dispatching (with static dispatching > corresponding to method overloading in C++, and runtime dispatching > corresponding to virtual methods in C++), This isn't quite right. C++ does not have anything directly corresponding to static dispatch. Method overloading in C++ corresponds to overloading in Ada. > would be possible only by using a class-wide type, such as > My_Type1'Class in the first parameter of a procedure or in the > return value of a function. No, but close. You need to pass a class-wide _object_ to a primitive subprogram to get dispatching. Complete compilable example: package Class_Wide_Aux is type My_Type1 is tagged record Field1 : Integer; Field2 : Integer; end record; procedure Foo (Item : in My_Type1); type My_Type2 is new My_Type1 with record Field3 : Integer; Field4 : Integer; end record; procedure Foo (Item : in My_Type2); end Class_Wide_Aux; with Ada.Text_IO; package body Class_Wide_Aux is procedure Foo (Item : in My_Type1) is begin Ada.Text_Io.Put_Line ("Foo (My_Type1)" & Integer'Image (Item.Field1)); end Foo; procedure Foo (Item : in My_Type2) is begin Ada.Text_Io.Put_Line ("Foo (My_Type2)" & Integer'Image (Item.Field3)); end Foo; end Class_Wide_Aux; with Class_Wide_Aux; use Class_Wide_Aux; procedure Class_Wide is function Get_An_Object (From : in Integer) return My_Type1'Class is begin if From = 1 then return My_Type1'(1, 2); else return My_Type2'(1, 2, 3, 4); end if; end Get_An_Object; Class_Wide_Obj_1 : My_Type1'Class := Get_An_Object (1); Class_Wide_Obj_2 : My_Type1'Class := Get_An_Object (2); begin Foo (Class_Wide_Obj_1); Foo (Class_Wide_Obj_2); end Class_Wide; The call to Foo will dispatch on the actual type of Class_Wide_Obj_*: gnatmake class_wide gcc -c -I./ -I.. -I- ..\class_wide.adb gnatbind -aO./ -I.. -I- -x class_wide.ali gnatlink class_wide.ali ./class_wide.exe Foo (My_Type1) 1 Foo (My_Type2) 3 > First of all, how do I accomplish returning a reference in Ada? Why is this "first"? There is nothing corresponding to a C++ "reference" in Ada; the closest thing is a constant access type. Ah. In C++, the only way to get a class-wide object is with a pointer. You can declare a class-wide pointer in Ada type Class_Wide_Access_Type1 is access all My_Type1'Class; but it is not necessary, as the example above shows. > What is the default behaviour of parameter passing and return in > Ada? Someone said here that if I use an "in" parameter in a > procedure or function definition, the object will be passed by > reference. What about the returing of objects? Are they returned by > copy or returned by reference? Copy or reference is orthogonal to in/out/return; the compiler is free to choose the best method for each subprogram. Except that tagged and fully limited types are always by-reference, to avoid problems that I can never quite remember :). > If I use a class-wide type, like My_Type1'Class, what kind of object > is that? Is it similar to Java's "object.class"? Class_Wide_Obj_1 is an object of type My_Type1'Class, which is a "class-wide type". > What's the difference between passing a class-wide type as an in/out > parameter of a procedure, and passing an access to it? > i.e. the difference between > > procedure Proc( Param : in out Type'Class ); This is not dispatching. Proc should do something that is truly proper for all derived types, or it should dispatch internally. > type Type_Class_Access is access Type'Class; > procedure Proc( Param : in Type_Class_Access ); This is not dispatching, but is class-wide. To get dispatching when you need a pointer, use an access parameter: procedure Foo (Item : access My_Type1); However, you generally don't need pointers in Ada. Well, sometimes you really do, but you should start by assuming you don't. There are many things C++ needs pointers for that Ada doesn't. > I think I know what run-time dynamic dispatching, class-wide types and > derived types refer to, but I'm not sure about implicit type conversions > that I can use. > > For example, how do I get an access to an object in an expression? > > Like, I have > I'll assume: type B is ...; type B_Access is access all B' > A : B ; This should be: A : aliased B; The compiler needs to know you will be using a pointer to A. > C : access B; This should be : C : B_Access; > how do I assign A to C? they are of different types, so you can't. Perhaps you meant "how do I make C point to A": C := A'Access; Note that there are "accessibility rules" that limit this; I'll leave that for another time (read your book :). > I tried to use the pointer-like semantics of access to class-wide types, but > I ended up with doing manual type conversions (or casting) all over. Is that > normal? No. If you find yourself doing type conversions, you are doing something wrong. > > Or, try to explain here what you mean by "object-oriented". Use > > either C++ or Ada terms, but try to be very explicit. Then we can > > tell you how to do that correctly in Ada. > > With object-oriented, I mean programming with classes of objects. Is that > explicit enough? Nope, sorry. Terms like "inheritance", "dynamic dispatch", "polymorphism", "overriding", "information hiding", "abstract data type", can all be part of "object-oriented", but are all very different from each other. Ada 83, and even C, support "classes of objects", but that's probably not what you mean. > In the "Ada 95: Guide for C/C++ Programmers", the author used only access to > class-wide types, and some people here say that you don't really need them, > and I'd like to know why and how I could use the more implicit semantics of > parameter passing to get the same effect. See the above example. That's a very bad thing for the book to do. It is the closest match to the "C++ way", but a _good_ book would point out how to do it better in Ada. > I thought by using this newsgroup, I could be spared from reading in > the Ada 95 Rationale. Which is very explicit, but also verbose, and > I'd like to make my learning process quicker. ;-) Well, yes, asking here is better than reading the Rationale. But a book like Barnes or Cohen is a better place to start. > Also, some things aren't explained properly in the Rationale, > because it assumes the reader is familiar with Ada. Yes; it's mainly for compiler implementers and language lawyers. > English is a foreign language to me, > and I'd rather not read umpteen pages of Ada language theory when I > can avoid it! ;-) ) You English looks very good to me, but that does make it harder. See www.adapower.com for reviews of other books you can get; I suspect you will want "Ada as a Second Language"; it's the most language-lawyer like, while still being more accessible than the Ada Rationale. Welcome to the wonderful world of Ada; the only way to program :). -- -- Stephe PS. Thank you for dragging this newsgroup back to its roots; explaining how to use Ada :).