* 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