TEAM-ADA Archives

Team Ada: Ada Programming Language Advocacy


Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Condense Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
"Team Ada: Ada Advocacy Issues (83 & 95)" <[log in to unmask]>
"Robert I. Eachus" <[log in to unmask]>
Thu, 5 Jun 1997 20:43:15 -0400
"Robert I. Eachus" <[log in to unmask]>
text/plain (64 lines)
   Heath White ([log in to unmask]) said:

  > One of the main headaches this causes occurs when you already have
  > a tagged hierarchy of types.  You want to derive off from it, but
  > you want the new type to have controlled behavior.  There is no
  > good way to do this.

   Of course there is, but in part it is non-intuitive...

  If you are adding a component that needs to be controlled, the
controlledness is a property of the component, and the language
supports that correctly.  It has to, since you might not be aware that
the component you are adding to a non-controlled class is controlled.

  The more "troubling" case is when the addition of a component
creates a need to finalize the containing structure.  Access
discriminants allow the compontent to see the containing structure.

  I keep meaning to create an abstraction which deals with the most
common sort of such extensions separate from other "building block"
tagged components.  It is less than twenty lines long--but choosing
some of those lines correctly takes thought.  Hmmm...

  with Ada.Finalization;
    type Uncontrolled(<>) is abstract tagged limited private;
    with procedure Finalize(Object: in out Uncontrolled);
  package Add_Finalization is
    type Controlled is new Uncontrolled with private;
    type Component(Parent: access Controlled) is new
       Ada.Finalization.Limited_Controlled with null record;
    type Controlled is new Uncontrolled with record
       Controller: Component(Controlled'Access); end record;
    procedure Finalize(Object: in out Component);
  end Add_Finalization;

  package body Add_Finalization is
    procedure Finalize(Object: in out Component) is
    begin Finalize(Uncontrolled(Object.Parent.all));
    end Finalize;
  end Add_Finalization;

  (Untested, but compiled, code. Comments and improvements welcome.)

  This version has the side effect of making the extended type
limited.  The body for a non-limited version is much more complex
because you have to use record with an access value as a
non-discriminant, then track assignment and copying using Intialize
and Adjust.  (Left as an exercise for the reader.)

  There is however one "can't be avoided" problem.  The order in which
the finalization of two extensions will be called is determined in
part by the subclassing order (see 7.6.1(9)) and in part by whether or
not there is an access discriminant.  If you have too many components
trying to finalize things, the ordering can get to be a problem.

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...