* Usefulness of classwide "out" parameter
@ 1999-03-15 0:00 okellogg
1999-03-15 0:00 ` Joachim Schroeer
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: okellogg @ 1999-03-15 0:00 UTC (permalink / raw)
Hi,
Has anyone ever used a classwide subprogram parameter with
mode "out" ?
For example,
type Mytype is tagged null record;
procedure Proc (Result : out Mytype'Class);
The problem I have with this is, I cannot assign another variable
to the out parameter (that would change the tag, which is not
possible.)
Am I correct in asserting that classwide parameters of mode "out"
are not terribly useful? What would a practical application of this
look like?
I am appending an example that shows the problem.
Thanks,
O. Kellogg
e-mail: oliver.kellogg@vs.dasa.de
-- base.ads
package Base is
type Mytype is tagged null record;
procedure Proc (Result : out Mytype'Class);
end Base;
-- base-derived1.ads
package Base.Derived1 is
type Deriv1 is new Mytype with null record;
end Base.Derived1;
-- base-derived2.ads
package Base.Derived2 is
type Deriv2 is new Mytype with null record;
end Base.Derived2;
-- base.adb
with Base.Derived1, Base.Derived2;
package body Base is
V1 : Base.Derived1.Deriv1;
V2 : Base.Derived2.Deriv2;
Some_Flag : Boolean := False;
procedure Proc (Result : out Mytype'Class) is
begin
if Some_Flag then
Result := V1; -- GNAT says:
else
Result := V2; -- dynamically tagged expression required
end if;
end Proc;
end Base;
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Usefulness of classwide "out" parameter
1999-03-15 0:00 Usefulness of classwide "out" parameter okellogg
@ 1999-03-15 0:00 ` Joachim Schroeer
1999-03-15 0:00 ` Matthew Heaney
1999-03-17 0:00 ` Nick Roberts
2 siblings, 0 replies; 4+ messages in thread
From: Joachim Schroeer @ 1999-03-15 0:00 UTC (permalink / raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1341 bytes --]
okellogg@my-dejanews.com schrieb in Nachricht
<7cikku$d4k$1@nnrp1.dejanews.com>...
Your logic may be implemented by a function (func below) returning a
classwide type or by using a classwide access type for the out
parameter of procedure proc. Then the 2 objects in base.adb have to
be aliased.
The attached modified code compiles with ObjectAda and GNAT.
J. Schr�er
-- base.ads
package Base is
type Mytype is tagged null record;
function Func return Mytype'Class;
type Mytype_Access is access all Mytype'Class;
procedure Proc (Result : out Mytype_Access);
end Base;
-- base-derived1.ads
package Base.Derived1 is
type Deriv1 is new Mytype with null record;
end Base.Derived1;
-- base-derived2.ads
package Base.Derived2 is
type Deriv2 is new Mytype with null record;
end Base.Derived2;
-- base.adb
with Base.Derived1, Base.Derived2;
package body Base is
V1 : aliased Base.Derived1.Deriv1;
V2 : aliased Base.Derived2.Deriv2;
Some_Flag : Boolean := False;
function Func return Mytype'Class is
begin
if Some_Flag then
return V1;
else
return V2;
end if;
end Func;
procedure Proc (Result : out Mytype_Access) is
begin
if Some_Flag then
Result := V1'access;
else
Result := V2'access;
end if;
end Proc;
end Base;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Usefulness of classwide "out" parameter
1999-03-15 0:00 Usefulness of classwide "out" parameter okellogg
1999-03-15 0:00 ` Joachim Schroeer
@ 1999-03-15 0:00 ` Matthew Heaney
1999-03-17 0:00 ` Nick Roberts
2 siblings, 0 replies; 4+ messages in thread
From: Matthew Heaney @ 1999-03-15 0:00 UTC (permalink / raw)
okellogg@my-dejanews.com writes:
> Has anyone ever used a classwide subprogram parameter with mode "out"?
No, because it's not very useful.
> For example,
>
> type Mytype is tagged null record;
> procedure Proc (Result : out Mytype'Class);
>
> The problem I have with this is, I cannot assign another variable
> to the out parameter (that would change the tag, which is not
> possible.)
The only thing you could do assign the object, if the tag happened to
match. Otherwise, you'll just get tag check errors.
> Am I correct in asserting that classwide parameters of mode "out" are
> not terribly useful?
That is indeed the case.
> What would a practical application of this look like?
Can you return a class-wide type as a function return instead?
Something like:
function Func return MyType'Class;
> I am appending an example that shows the problem.
> -- base.ads
> package Base is
> type Mytype is tagged null record;
> procedure Proc (Result : out Mytype'Class);
> end Base;
This type is non-limited, so returning a class-wide type as the result
of a function would be OK.
> with Base.Derived1, Base.Derived2;
> package body Base is
> V1 : Base.Derived1.Deriv1;
> V2 : Base.Derived2.Deriv2;
> Some_Flag : Boolean := False;
> procedure Proc (Result : out Mytype'Class) is
> begin
> if Some_Flag then
> Result := V1; -- GNAT says:
> else
> Result := V2; -- dynamically tagged expression required
> end if;
> end Proc;
> end Base;
How about this:
function Func return Mytype'Class is
begin
if Some_Flag then
return V1;
else
return V2;
end if;
end Func;
This should be fine for what you're trying to do. But...
...what you're doing looks suspiciously like the singleton pattern. If
you're returning the value of a statically allocated instance, then you
can just as easily return a pointer to it:
type Mytype_Access is access constant Mytype'Class;
package body P is
V1 : aliased D1;
V2 : aliased D2;
procedure Proc (Result : out Mytype_Access) is
begin
if Some_Flag then
Result := V1'Access;
else
Result := V2'Access;
end Proc;
or
function Func return Mytype_Access is
begin
if Some_Flag then
return V1'Access;
else
return V2'Access;
end if;
end Func;
If you want to enforce cardinality, or just control how instances are
created, then you can declare the type as limited and indefinite.
Singletons are implemented by returning a pointer to the statically
declared instance in the body, and declaring primitive operations of the
type to take access parameters.
See my most recent post, "State Pattern," in the Mar 99 ACM patterns
archive, for an example of how to do this. The article "Abstract
Factory Revisited" has lots of info about these idioms too.
<http://www.acm.org/archives/patterns.html>
You can subscribe to the patterns list by sending a message with the
body
subscribe patterns <your full name>
to the ACM mailing list server.
<mailto:listserv@acm.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Usefulness of classwide "out" parameter
1999-03-15 0:00 Usefulness of classwide "out" parameter okellogg
1999-03-15 0:00 ` Joachim Schroeer
1999-03-15 0:00 ` Matthew Heaney
@ 1999-03-17 0:00 ` Nick Roberts
2 siblings, 0 replies; 4+ messages in thread
From: Nick Roberts @ 1999-03-17 0:00 UTC (permalink / raw)
I think 'out' parameters of a classwide type will be useful in some
situations. I am particularly thinking of a 'wrapper' procedure which
redispatches on the classwide parameter. For example, consider an abstract
tagged type T, and suppose that it has an abstract procedure:
procedure Create (Obj: out T) is abstract;
so that all types derived from T must have a 'Create' procedure, which
presumably initialises an object of that type in the appropriate way.
Now, supposing you wanted to monitor the creation of all objects of types
derived from T (perhaps writing a message onto a log file for each
occurrence). You could do this by declaring a 'wrapper' procedure:
procedure Monitored_Create (Obj: out T'Class) is
begin
Put_Line(Log_File,"Creating object of type " &
Ada.Tags.Expanded_Name(Obj'Tag));
Create(Obj);
end;
This procedure outputs a message onto a log file (using the known tag of the
object actually passed), and then redispatches on that object to the
requisite 'Create' procedure.
It may be that 'out' parameters of a classwide type are not likely to be
used very often, but, like many aspects of the language, I suspect they will
be useful every now and then! (A bit like me, really ;-)
-------------------------------------
Nick Roberts
-------------------------------------
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~1999-03-17 0:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-03-15 0:00 Usefulness of classwide "out" parameter okellogg
1999-03-15 0:00 ` Joachim Schroeer
1999-03-15 0:00 ` Matthew Heaney
1999-03-17 0:00 ` Nick Roberts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox