comp.lang.ada
 help / color / mirror / Atom feed
* private classes
@ 2004-10-02 20:35 Rick Santa-Cruz
  2004-10-02 21:12 ` Rick Santa-Cruz
  2004-10-03 16:36 ` Martin Krischik
  0 siblings, 2 replies; 4+ messages in thread
From: Rick Santa-Cruz @ 2004-10-02 20:35 UTC (permalink / raw)


Hi,

sorry for so many question, but always when I thought I understand it, I 
read further and see a new problem... so given the following source-code:
package Classes is
 type Base_1 is tagged private;

 type Derived_1 is new Base_1 with private;

 procedure Proc(B: Base_1);

 private
  type Base_1 is tagged record
   Number: Integer;
  end record;

  type Derived_1 is new Base_1 with null record;
end Classes;

package body Classes is
 procedure Proc(b: Base_1) is
 begin
  null;
 end Proc;
end Classes;

with Classes;

procedure main is
 D: Classes.Derived_1;
begin
 Classes.Proc(D);
end Main;

I get an error in calling Classes.Proc(D). Although I thought that cause 
Derived_1 inherits from Base_1 the call should be possible. In fact exactly 
this I found in the book from John English in chapter 14.5. Why can't I 
compile such, although I thought the function Proc is visible for clients of 
the package Classes.
My second question is then, if the above does not work (and I really wonder 
why) then, what would it make for a difference if instead of writing:
type Derived_1 is new Base_1 with private;
I write:
type Derived_1 is private;
and then in the private-part of the package:
type Derived_1 is new Base_1 with null_record;
What would be the difference between that and the definition above?

Thanks tons in advance, cause I really start to become desperate ;(.

Bye,
Rick





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

* Re: private classes
  2004-10-02 20:35 private classes Rick Santa-Cruz
@ 2004-10-02 21:12 ` Rick Santa-Cruz
  2004-10-03 19:11   ` Ludovic Brenta
  2004-10-03 16:36 ` Martin Krischik
  1 sibling, 1 reply; 4+ messages in thread
From: Rick Santa-Cruz @ 2004-10-02 21:12 UTC (permalink / raw)


Hi,

> package Classes is
> type Base_1 is tagged private;
>
> type Derived_1 is new Base_1 with private;
>
> procedure Proc(B: Base_1);
>
> private
>  type Base_1 is tagged record
>   Number: Integer;
>  end record;
>
>  type Derived_1 is new Base_1 with null record;
> end Classes;
>
> package body Classes is
> procedure Proc(b: Base_1) is
> begin
>  null;
> end Proc;
> end Classes;
>
> with Classes;
>
> procedure main is
> D: Classes.Derived_1;
> begin
> Classes.Proc(D);
> end Main;
Ok, I got it. The declaration of the procedure has to be before the "type 
Derived_1 is new Base_1 with private;". Although I don't understand the 
sense of this, but ok ;).

Bye,
Rick





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

* Re: private classes
  2004-10-02 20:35 private classes Rick Santa-Cruz
  2004-10-02 21:12 ` Rick Santa-Cruz
@ 2004-10-03 16:36 ` Martin Krischik
  1 sibling, 0 replies; 4+ messages in thread
From: Martin Krischik @ 2004-10-03 16:36 UTC (permalink / raw)


Rick Santa-Cruz wrote:

> Hi,
> 
> sorry for so many question, but always when I thought I understand it, I
> read further and see a new problem... so given the following source-code:
> package Classes is
>  type Base_1 is tagged private;
> 
>  type Derived_1 is new Base_1 with private;
> 
>  procedure Proc(B: Base_1);
> 
>  private
>   type Base_1 is tagged record
>    Number: Integer;
>   end record;
> 
>   type Derived_1 is new Base_1 with null record;
> end Classes;
> 
> package body Classes is
>  procedure Proc(b: Base_1) is
>  begin
>   null;
>  end Proc;
> end Classes;
> 
> with Classes;
> 
> procedure main is
>  D: Classes.Derived_1;

     D_Class : Classes.Base_1'Base renames Classes.Base_1'Base (D);

> begin
>  Classes.Proc(D);

     Classes.Proc(D_Class);

> end Main;
> 
> I get an error in calling Classes.Proc(D). Although I thought that cause
> Derived_1 inherits from Base_1 the call should be possible. In fact
> exactly this I found in the book from John English in chapter 14.5. Why
> can't I compile such, although I thought the function Proc is visible for
> clients of the package Classes.

It's the strong typing in Ada. For a C++ programmer used to using pointers
and references which convert itself this might come as a suprise. Here you
should remember that "this" is indeed a pointer.

> My second question is then, if the above does not work

Well it does work with the fix I have made. You should note that Ada does
not automaticly slice objects. This has advantages and disadvantages. I
show you the advantage:

type Base_1_Access is access Base_1;

D_Pointer = new Base_1'(D_Class);

In C++ the operator new would slice D down to Base_1 - that is all the
Derived_1 information will be lost and only the copy constructor of Base_1
is called. In Ada it isn't. Ada will copy the complete object and use the
Adjust from Derived_1. And that allows for the equivalent of "vector
<Base_1>" to be as usefull as "vector <Base_1*>". 

{Ada.Containers.Vector will be added in Ada 2005 - Test versions are
available on the net.}

As a price you pay for this quite handy feature you need to use Base_1'Base
whenever you don't know what actual class an object could be.

With Regards

Martin
-- 
mailto://krischik@users.sourceforge.net
http://www.ada.krischik.com




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

* Re: private classes
  2004-10-02 21:12 ` Rick Santa-Cruz
@ 2004-10-03 19:11   ` Ludovic Brenta
  0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Brenta @ 2004-10-03 19:11 UTC (permalink / raw)


"Rick Santa-Cruz" writes:
> Ok, I got it. The declaration of the procedure has to be before the "type 
> Derived_1 is new Base_1 with private;". Although I don't understand the 
> sense of this, but ok ;).

Dennis Lee Bieber already explained why in a previous post.  I think
his explanation is good and intuitive.  The technical term for this is
"freezing rules", defined formally in RM 13.14.  You might be
interested in reading that.  Note that few people actually bother to
really understand all the implications of freezing rules; they are of
interest primarily to compiler writers.

In your case, the declaration of type Derived_1 freezes type Base_1
(RM 13.14(7): "The declaration of a record extension causes freezing
of the parent subtype.").  After this point, no more primitive
subprograms ("methods") can be added to type Base_1.  This means that:

- you can declare procedure Proc (B : Base_1), but it is not a
  primitive subprogram, just a regular one.

- no dynamic dispatching can take place, since dynamic dispatching
  only involves primitive subprograms.

-- 
Ludovic Brenta.



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

end of thread, other threads:[~2004-10-03 19:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-02 20:35 private classes Rick Santa-Cruz
2004-10-02 21:12 ` Rick Santa-Cruz
2004-10-03 19:11   ` Ludovic Brenta
2004-10-03 16:36 ` Martin Krischik

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