comp.lang.ada
 help / color / mirror / Atom feed
* Ada tagged types not as powerful as C++ for dispatching???
@ 1997-08-15  0:00 Troy Noble
  1997-08-16  0:00 ` Jon S Anthony
  0 siblings, 1 reply; 4+ messages in thread
From: Troy Noble @ 1997-08-15  0:00 UTC (permalink / raw)
  To: tmnoble


Ok, I know Ada95 is very powerful, and there's
probably an easy answer to my question.  I had
to get attention somehow, though...  I'm sure it's
just 'cause I'm a "newbie" to Ada (but not to OO).

My question is related to polymorphism and dynamic
dispatching with tagged record types.  Hopefully
some Ada "black-belt" can show me the errors of my
ways.  Cohen sure talked me in circles, and now I'm
confused.  That guy's too smart for me to follow
sometimes.

Here's what I've got so far.  As you can hopefully tell,
I've tried to simplify the situation considerably in order
to hone in on the real issue.  Trust me, I have good
reasons for wanting to do what I'm doing.  In fact,
this works well in every other OO language I've used
including C++, Smalltalk, Eiffel, Python, and even Perl
(polymorphism & dynamic dispatch are germane to OO,
and since Ada is OO... there's got to be some way
to do it right in Ada too! I hope.).

  package Figures is
  type Figure is tagged record
    ...   -- in true Cohen style, significant detail omitted.
  end record;

  type Circle is new Figure with record
    ...
  end record;

  type Figure_Ptr is access all Figure'Class;
  type Circle_Ptr is access all Figures.Circle;

  end Figures;

Now, in another package I want to dynamically create
an instance of a Circle and keep an access
variable of type Circle_Ptr (so I can treat it like
a Circle sometimes) and also keep an access variable
of type Figure_Ptr (so I can dispatch).  And the
following works just fine:

  with Figures;

  procedure Test_Figures is
    C2_Ptr  : Circle_Ptr;
    A_Figure: Figures.Figure_Ptr;
  begin
    A_Figure := new Figures.Circle;        -- line (1)
    C2_Ptr := Circle_Ptr(A_Figure);        -- line (2)
  end;

Now the real question is, what syntax do I use if I
want to dynamically allocate C2_Ptr FIRST and then have
A_Figure be an access type that "points" to the same
instance.  In other words, reverse the order in which
I do lines (1) and (2) above.

From what I've been able to ascertain, this is not nearly
as syntactically simple to do, but it is the situation
I'm presently faced with.

I've tried the following, but it actually creates a
COPY of the original circle and then converts the
type to Figures.Figure'Class.  What I really wanted
was to get back just another access to the same
instance as C2_Ptr "points to".

  C2_Ptr   := new Figures.Circle;
  A_Figure := new Figures.Figure'Class'(Figures.Figure'Class
                       (C2_Ptr.all));
     -- this creates a new COPY of object?!?  Not the desired effect.

I've also tried other variations of type conversions,
most of which seemed intuitive to me, but the compiler
did not like:

  C2_Ptr   := new Figures.Circle;
  A_Figure := C2_Ptr;   -- expected Figure_Ptr, found Circle_Ptr
  A_Figure := Figures.Figure_Ptr'(C2_Ptr);   -- same thing as above
  A_Figure := Figures.Figure_Ptr(C2_Ptr);
     -- previous line: operand has deeper accessibility level than
target

What am I missing?

To give another perspective of what I'm trying to
do (for those who "know" C++)... I would normally
do the following in C++ with great success.

class Figure { ... };
class Circle : public Figure { ... };
void someRoutine {
  Figure *aFigure;
  Circle *C2_Ptr;

  C2_Ptr  = new Circle;
  aFigure = C2_Ptr;

  // Now I can dispatch calls via aFigure, like aFigure->Draw(),
  // which will invoke Circle's Draw() member function

  // I can also set values of the Circle, like radius, via C2_Ptr
  C2_Ptr->radius=1.5;
}

Hope this makes sense.

Thanks in advance for any expert advice.

Troy





^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Ada tagged types not as powerful as C++ for dispatching???
  1997-08-15  0:00 Ada tagged types not as powerful as C++ for dispatching??? Troy Noble
@ 1997-08-16  0:00 ` Jon S Anthony
  1997-08-18  0:00   ` Troy Noble
  0 siblings, 1 reply; 4+ messages in thread
From: Jon S Anthony @ 1997-08-16  0:00 UTC (permalink / raw)



In article <33F4D31F.6E511B93@mci.com> Troy Noble <Troy.Noble@mci.com> writes:

>   A_Figure := Figures.Figure_Ptr(C2_Ptr);
>   -- previous line: operand has deeper accessibility level than target

This does not look correct.  Neither the access types nor the object
decls have different access levels.  The following works fine under
both gnat305 and gnat309 (both sparc.solaris)

with Figures;  use Figures;
procedure Fig_Test is
    C2_Ptr  : Circle_Ptr;
    A_Figure: Figures.Figure_Ptr;
begin
    A_Figure := new Figures.Circle;        -- line (1)
    C2_Ptr := Circle_Ptr(A_Figure);        -- line (2)
    C2_Ptr := new Figures.Circle;
    A_Figure := Figure_Ptr(C2_Ptr);
end;


What compiler are you using?

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Ada tagged types not as powerful as C++ for dispatching???
  1997-08-16  0:00 ` Jon S Anthony
@ 1997-08-18  0:00   ` Troy Noble
  1997-08-18  0:00     ` Robert A Duff
  0 siblings, 1 reply; 4+ messages in thread
From: Troy Noble @ 1997-08-18  0:00 UTC (permalink / raw)



Jon,

I'm using GNAT 3.09 on Linux and on Win32.  I got the same
results in both places.

The fact that you got it to work caused me to go back and
take another look.  What I uncovered may or may not be a
bug in GNAT, but I'm not sure I know Ada95 well enough
to make that call.  See what you think...

The only difference between what you tried and what I tried
is that in my message on this newsgroup I put the definition
of Circle_Ptr INSIDE package Figures.  In my non-working
code I had defined Circle_Ptr INSIDE my procedure
Test_Figures.  Apparently GNAT was getting confused 
when trying to resolve the accessibility levels between the
"locally" scoped Circle_Ptr definition and the "package"
scoped Figure_Ptr definition, or else what I did was just
plain wrong.

In short, I moved the line:

type Circle_Ptr is access all Circle;

from inside procedure Test_Figures to inside package
Figures... and everything works fine now.  I can
create Circle's and use Figure_Ptr or Circle_Ptr to
"point" to them, then I can convert back-n-forth
between Figure_Ptr and Circle_Ptr as desired.

Much nice... and works as I'd expect for my OO
dispatching purposes.

Thanks very much for testing this and answering my
question.

Do you think this is a bug in GNAT that I should report,
or was it in fact detecting the error properly?

Thanks again, Troy

Jon S Anthony <jsa@alexandria.organon.com> wrote in article
<JSA.97Aug16191349@alexandria.organon.com>...
> In article <33F4D31F.6E511B93@mci.com> Troy Noble <Troy.Noble@mci.com>
writes:
> 
> >   A_Figure := Figures.Figure_Ptr(C2_Ptr);
> >   -- previous line: operand has deeper accessibility level than target
> 
> This does not look correct.  Neither the access types nor the object
> decls have different access levels.  The following works fine under
> both gnat305 and gnat309 (both sparc.solaris)
> 
> with Figures;  use Figures;
> procedure Fig_Test is
>     C2_Ptr  : Circle_Ptr;
>     A_Figure: Figures.Figure_Ptr;
> begin
>     A_Figure := new Figures.Circle;        -- line (1)
>     C2_Ptr := Circle_Ptr(A_Figure);        -- line (2)
>     C2_Ptr := new Figures.Circle;
>     A_Figure := Figure_Ptr(C2_Ptr);
> end;
> 
> 
> What compiler are you using?
> 
> /Jon
> -- 
> Jon Anthony
> OMI, Belmont, MA 02178, 617.484.3383 
> "Nightmares - Ha!  The way my life's been going lately,
>  Who'd notice?"  -- Londo Mollari
> 




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Ada tagged types not as powerful as C++ for dispatching???
  1997-08-18  0:00   ` Troy Noble
@ 1997-08-18  0:00     ` Robert A Duff
  0 siblings, 0 replies; 4+ messages in thread
From: Robert A Duff @ 1997-08-18  0:00 UTC (permalink / raw)



In article <01bcab6a$f2061820$92165da6@csp3610x>,
Troy Noble <tmnoble@rmi.net> wrote:
>The only difference between what you tried and what I tried
>is that in my message on this newsgroup I put the definition
>of Circle_Ptr INSIDE package Figures.  In my non-working
>code I had defined Circle_Ptr INSIDE my procedure
>Test_Figures.

That explains it.  You can't convert from a more-nested access type to a
less-nested one, because that could create dangling pointers.  (There
are ways to do it -- e.g. using Unchecked_Access, but it's usually best
to just put the access types at library level.)

>Do you think this is a bug in GNAT that I should report,
>or was it in fact detecting the error properly?

GNAT is correct to complain.

- Bob




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1997-08-18  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-08-15  0:00 Ada tagged types not as powerful as C++ for dispatching??? Troy Noble
1997-08-16  0:00 ` Jon S Anthony
1997-08-18  0:00   ` Troy Noble
1997-08-18  0:00     ` Robert A Duff

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