comp.lang.ada
 help / color / mirror / Atom feed
From: Stephen Leake <Stephen.Leake@gsfc.nasa.gov>
Subject: Re: Polymorphism/Inheritence
Date: 1997/02/28
Date: 1997-02-28T00:00:00+00:00	[thread overview]
Message-ID: <3316F788.470A@gsfc.nasa.gov> (raw)
In-Reply-To: JSA.97Feb26163417@alexandria


In article <5f0pcc$5b9@news.cps.udayton.edu> abacon@cps.udayton.edu
(Adam C. Bacon) writes:
> [description of example; replaced with compilable code:]

package Parent is
   type Vehicle is tagged private;
   type Vehicle_Pointer is access Vehicle'Class;
private
   type Vehicle is tagged record
      Maker_ID : Integer;
   end record;
end Parent;

package Parent.Child is
   type Car is new Vehicle with private;

   procedure Create
      (Maker_ID : in Integer;
       Wheels : in Integer);

private
   type Car is new Vehicle with record
      Wheels : Integer;
   end record;
end Parent.Child;

package body Parent.Child is
   Pointer  : Vehicle_Pointer;

   procedure Create
      (Maker_ID : in Integer;
       Wheels : in Integer)
   is
      Temp_Car : Car := (Maker_ID, Wheels);
   begin
      Pointer := new Car;
      Pointer.all := Temp_Car;
   end Create;
end Parent.Child;

> >   Pointer.all := Temp_Car;
> >                  |
> >   dynamically tagged expression required

Jon Anthony replies with an informative discussion of class wide types,
and suggests:

> 
>     Pointer.all := Vehicle'Class(Temp_Car);
> 
> Now, this compiles and runs OK on GNAT 3.09.  But I don't know if it
> is really correct...
> 

This certainly works, and is consistent with the RM, as Jon points out.
This is a view conversion; it does not change the value of Temp_Car as
it copies it. Pointer.all is of type Vehicle'class; this is a different
type than Car, so a view conversion is required. 

However, depending on what Create really does, there are better ways to
do this. For example:

   procedure Create
      (Maker_ID : in Integer;
       Wheels : in Integer)
   is
   begin
      Pointer := new Car'(Maker_ID, Wheels);
   end Create;

This avoids the entire issue, and saves a copy operation. If Create
truly needs a Temp_Car for other reasons, then:

   procedure Create
      (Maker_ID : in Integer;
       Wheels : in Integer)
   is
      Temp_Car : Car'class;  -- error
   begin
      Pointer := new Car;
      ...
      mess with Pointer and/or Temp_Car
      ...
      Pointer.all := Temp_Car;
   end Create;

But class wide objects need initialization, so we try:

   procedure Create
      (Maker_ID : in Integer;
       Wheels : in Integer)
   is
      Temp_Car : Car'class := (Maker_ID, Wheels);
   begin
      Pointer := new Car;
      ...
      mess with Pointer and/or Temp_Car
      ...
      Pointer.all := Temp_Car;
   end Create;

This seems like it should work, but now I get:

      Temp_Car : Car'class := (Maker_ID, Wheels);
parent-child.adb:8:31: aggregate not available for limited array

This is a very weird message, since there are neither arrays nor limited
types present. I'll send it to gnat_report. 

What is this error trying to tell me?
-- 
- Stephe




  reply	other threads:[~1997-02-28  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-02-26  0:00 Polymorphism/Inheritence Adam C. Bacon
1997-02-26  0:00 ` Polymorphism/Inheritence Jon S Anthony
1997-02-28  0:00   ` Stephen Leake [this message]
1997-03-01  0:00   ` Polymorphism/Inheritence Robert Dewar
1997-03-03  0:00   ` Polymorphism/Inheritence Jon S Anthony
1997-02-27  0:00 ` Polymorphism/Inheritence Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox