Previous | Table of Contents | Next |
10.4.3.9. Controlled Types and Finalization
I hinted previously that Ada provides a mechanism that facilitates writing an application-specific garbage-collection scheme. Three activities must be supported:
This support is embodied in the standard library package Ada.Finalization.
1 package Ada.Finalization is 2 3 type Controlled is abstract tagged private; 4 procedure Initialize(Object : in out Controlled); 5 procedure Adjust (Object : in out Controlled); 6 procedure Finalize (Object : in out Controlled); 7 8 type Limited_Controlled is 9 abstract tagged limited private; 10 procedure Initialize 11 (Object : in out Limited_Controlled); 12 procedure Finalize 13 (Object : in out Limited_Controlled); 14 private 15 ... -- not specified by the language 16 end Ada.Finalization;
The type Ada.Finalization.Controlled is
The operations Initialize, Adjust, and Finalize can be overridden for a derived type. They are not abstract operations, however, so they need not be overridden. In this case, the root operations are essentially no-ops that have no discernible effect.
How do these operations work? Suppose you have
type MyType is new Ada.Finalization.Controlled with some_extension declare Object: MyType; begin Object := some_expression; ... end;
When control passes into the declare block, the declaration of Object is elaborated. Because MyType is derived from Controlled, its (inherited or overriding) Initialize operation is now automatically called.
Now control passes to the assignment statement. Three actions occur:
Finally, when control passes out of the block, Object goes out of scope and is destroyed (typically, popped off the system stack). Before this happens, Finalize(Object) is automatically called.
Suppose MyType represents a linked list. Deriving it from Controlled allows me to develop my own garbage collection in terms of overriding operations.
Ada.Finalization provides a clean and easy-to-understand equivalent of the constructor and destructor operations of other languages and moreover provides user-defined assignment in a fashion that is well-integrated with the other operations.
It is now easy to understand the rest of the interface of HB.Lists_Generic. The type List is derived from Ada.Finalization.Controlled. I declare three overriding operations; putting them in the private part ensures that a client cannot call them directly.
Previous | Table of Contents | Next |