From: "Nick Roberts" <nick.roberts@acm.org>
Subject: Re: Type conversions on pool-specific access types
Date: Thu, 16 Oct 2003 21:28:07 +0100
Date: 2003-10-16T21:28:07+01:00 [thread overview]
Message-ID: <bmmv0o$olqei$1@ID-25716.news.uni-berlin.de> (raw)
In-Reply-To: g5ksovoq9nkg0tb53rgrn40vjjl7l5cqkb@4ax.com
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:g5ksovoq9nkg0tb53rgrn40vjjl7l5cqkb@4ax.com...
> > ...
> > declare
> > Ptr : Base_Ptr := new Derived;
> > begin
> > Foo(Ptr);
>
> Yes, in this case. But consider specialized containers of
> Derived descendants:
>
> procedure Derived_Specific (X : Derived);
> type Array_Of_Derived is array (...) of Derived_Ptr;
>
> Now you can call Derived_Specific on any element of
> Array_Of_Derived without an explicit type conversion.
> It is also type safe. If I have only Base_Ptr, I lose that
> advantage and forced to always work in the terms of
> the base type and what is worse, to make casts.
In this situation, I suggest you declare:
type Derived_Ptr is access Derived'Class;
type Array_Of_Derived is array (...) of Derived_Ptr;
exactly as you suggest, so you can call:
Derived_Specific( Array_Of_Derived(...).all );
If you now wish to call Foo for an object designated by a component of the
Array_Of_Derived array, you do indeed need to do a conversion. I think this
can be adequately achieved in Ada 95 by the use of an intermediate general
access type:
type General_Base_Ptr is access all Base'Class;
procedure Foo (Object: in General_Base_Ptr);
Now we can call Foo for objects of type Base_Ptr or Derived_Ptr:
X: Base_Ptr;
...
Foo( General_Base_Ptr(X) );
Foo( General_Base_Ptr(Array_Of_Derived(...)) );
If you do not need to be able to pass null values, an alternative is to make
the parameter to Foo of an anonymous access type:
procedure Foo (Object: access Base'Class);
Then the conversions are implicit:
Foo( X );
Foo( Array_Of_Derived(...) );
I recognise that this is not the neatest solution imaginable, but I think it
works, and will be reasonably efficient. It has the possible advantage that
you could choose to have Base_Ptr and Derived_Ptr objects stored in
different pools (and the new Foo will still work, since it accepts a general
access type).
> [Finalize should not deallocate Object]
> Theoretically true, but practically, consider a situation
> when objects have to be always allocated in a specific
> pool. For example, on a user-defined stack. Further each
> object has to remove itself from some list. It is made
> upon finalization. The problem is that in this case you
> cannot use the advantages of thin pool-specific pointers.
I repeat that a controlled object should not attempt to deallocate itself
during its own finalisation. In order to cause the deallocation of an
object, an instance of Unchecked_Deallocation should be called at the
appropriate time, which can be expected to: (1) call Finalize for the
object; (2) call Deallocate for the object's pool.
One way to obtain the calling of an instance of Unchecked_Deallocation for
all the objects in a linked list is to declare a controlled type which
contains a pointer to one of the objects in the list, and to implement the
Finalize procedure of this type to chase down the list deallocating objects
as it goes. For example:
type My_Object;
type My_Object_Ptr is access My_Object;
type My_Object is new Ada.Finalization.Controlled with
record
Next: My_Object_Ptr;
...
end record;
type My_Object_List is new Ada.Finalization.Controlled with
record
First: My_Object_Ptr;
...
end record;
procedure Free is new
Ada.Unchecked_Deallocation(My_Object,My_Object_Ptr);
procedure Finalize (List: in out My_Object_List) is
Obj, Tmp: My_Object_Ptr;
begin
Obj := List.First;
List.First := null;
while Obj /= null loop
Tmp := Obj;
Obj := Obj.Next;
Free(Tmp); -- will call member's Finalize and its pool's Deallocate
end loop;
end Finalize;
procedure Do_Something_Using_a_List is
L: My_Object_List;
begin
... -- add members to the list L
end; -- L will be finalised here, which will cause the whole list to be
finalised and freed properly
Hope this is helpful!
--
Regards,
Nick Roberts
next prev parent reply other threads:[~2003-10-16 20:28 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-13 10:34 Type conversions on pool-specific access types Dmitry A. Kazakov
2003-10-16 1:43 ` Nick Roberts
2003-10-16 12:13 ` Dmitry A. Kazakov
2003-10-16 20:28 ` Nick Roberts [this message]
2003-10-17 4:27 ` Nick Roberts
2003-10-18 9:59 ` Dmitry A. Kazakov
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox