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,4d8b56262a702d36 X-Google-Attributes: gid103376,public From: Samuel Tardieu Subject: Re: Dispatching in Ada95 Date: 1996/04/19 Message-ID: #1/1 X-Deja-AN: 148368042 sender: tardieu@gargantua.enst.fr references: content-type: text/plain; charset=iso-8859-1 organization: TELECOM Paris mime-version: 1.0 newsgroups: comp.lang.ada Date: 1996-04-19T00:00:00+00:00 List-Id: >>>>> "James" == James A Squire writes: James> Unless I am totally dense, in order for dispatching to work in James> this example as printed on page II-8, there is one vital James> element (which of course is left out of the example on II-8): James> "use New_Alert_System; use Emergency_Alert_System;" James> Otherwise, dispatching doesn't work, because once the 'Class James> attribute is used to figure out the actual type of the James> Alert'Class parameter in a given instance, and then the Ada83 James> rules kick in: check all overloaded subprograms _which are James> directly visible_ at that point in time and pick the only one James> that matches the parameter profile. I wouldn't say you're totally dense since I don't know you, but I think you have misunderstood how dispatching works :) You're right in saying that it will check a subprogram which is directly visible (if you don't give a prefix). But if your parameter is of a class-wide type, only a subprogram with the base type of this class-wide type needs to be visible. Let's take an example. We create a package AAA which defines a class A as well as a Create function, and a Get_Info function. package AAA is type A is tagged private; function Create return A; function Get_Info (X : A) return String; private ... end AAA; package body AAA is function Create return A is begin ... end Create; function Get_Info (X : A) return String is begin return "Type A object"; end Get_Info; end AAA; Then we create a BBB package which defined a class B (derived from AAA.A). This class gets an overloaded Get_Internal_Info method. with AAA; package BBB is type B is new AAA.A with private; function Create return B; function Get_Info (X : B) return String; private ... end BBB; package body BBB is function Create return B is begin ... end Create; function Get_Info (X : B) return String is begin return "Type B object"; end Get_Info; end BBB; Now, our main procedure T. T withes AAA, BBB and Text_IO, and uses all of them except BBB. An object of type A'Class is declared, and initialized to an object of type B. This is possible because B is derived from A. When Get_Info is called, the right one (B's one) is executed, although the one which is visible is AAA's one. with AAA, BBB, Ada.Text_IO; use AAA, Ada.Text_IO; procedure T is Var : constant A'Class := BBB.Create; begin Put_Line (Get_Info (Var)); end T; How does it work ? Simple : since Var is of a type A'Class, and a Get_Info function taking an argument of type A is in the scope, then a dynamic resolution will occur to check if a deeper Get_Info (on the path A->B) exists. One is found (BBB.Get_Info, which takes an argument of type B) and gets called, even if it's not directly visible. Note that if Var was declared as: Var : constant BBB.B := BBB.Create; the program wouldn't compile, because no Get_Info with an argument of type B is directly visible. I hope I've been clear enough and not too confusing :) Sam -- "La cervelle des petits enfants, ca doit avoir comme un petit gout de noisette" Charles Baudelaire