Tucker Taft wrote: > > If you want to prevent the possibility of forgetting initial > value assignment, you could specify unknown discriminants > in the private type declaration. E.g.: > > type Object_Type(<>) is private; > > The full type need not have any discriminants at all, but by > doing the private declaration this way, a user of the type outside > the package is required to initialize all object declarations, > because simply "X : Object_Type;" is illegal (Object_Type is an > "indefinite" (view of a) type). This is a good suggestion, but it only gets you about half way there. I want to be able to do the opposite as well: guarantee that *every* object creation causes one of my procedures to be called. Consider this example: ------------------------ with Ada.Finalization; use Ada.Finalization; package Final is type Finis(<>) is private; function Get_Count return Integer; function Create return Finis; private type Finis is new Controlled with null record; procedure Finalize (Obj : in out Finis); Null_Finis : constant Finis := (Controlled with null record); end Final; -------------------------- package body Final is Ref_Count : Integer := 0; procedure Finalize (Obj : in out Finis) is begin Ref_Count := Ref_Count - 1; end Finalize; function Get_Count return Integer is begin return Ref_Count; end Get_Count; function Create return Finis is begin Ref_Count := Ref_Count + 1; return Null_Finis; end Create; end Final; ---------------------------- with Final; with Text_Io; use Text_Io; with Ada.Finalization; use Ada.Finalization; procedure Finish is begin Put_Line ("Count is:" & Integer'Image (Final.Get_Count)); declare X : Final.Finis := Final.Create; begin Put_Line ("Count is:" & Integer'Image (Final.Get_Count)); end; Put_Line ("Count is:" & Integer'Image (Final.Get_Count)); end Finish; ---------------------------- The output of Finish is: Count is: 0 Count is: 0 Count is:-1 My understading is that we get this result because the object resulting from the Create call is finalized without having been initialized. So, in Ada 95, I can't figure out a way to do reference counting for every object created of my type. (In C++, this would be done with a private "static" data member in the class.) The following is not enough: ------------------------------- with Ada.Finalization; use Ada.Finalization; package Final is type Finis is new Controlled with null record; -- or with private -- Construct is a procedure, not a function, so that -- it cannot be called for object initialization procedure Construct (Obj : in out Finis; A : type1; B : type2 ... ); -- construction parameters procedure Initialize (Obj : in out Finis); procedure Finalize (Obj : in out Finis); end Final; -------------------------------- (where the body of Initialize increments the ref_count, the body of Finalize decrements ref_count), because it is not possible to keep the user from explicitly initializing objects of type Finis like this: F : Final.Finis := (Controlled with null record); This bypasses the call to Initialize. (I know I can guarantee that Initialize will be called if Finis is derived from Limited_Controlled, but this misses the point because then I would not be able to use functions as contructors, and would be stuck with discriminant values if I wanted parameters to be supplied at object declaration.) What would solve this problem (and a number of others), I think, is added support in Ada.Finalization for user-defined activity at the time of object creation. This could take the form: procedure Create (Object : in out Controlled); .... procedure Create (Object : in out Limited_Controlled); in the spec of Ada.Finalization. The semantics are: Create is called at object creation time, just before initialization. Symmetrically, we could add: procedure Destroy (Object : in out Controlled); .... procedure Destroy (Object : in out Limited_Controlled); Which have the semantics: Destroy is called when an object is destroyed, just after the last Finalize has been called for it before it goes out of existence. Adding a separate Destroy procedure would help clean up the current semantics of Finalize because a Finalize procedure actually does double duty in an Ada 95 program -- it handles both value-destruction and object-destruction. Ada 95 Initialize/Adjust/Finalize are not as flexible as C++ constructor/destructors because the have only to do with the *contents* of an object during its life *between* creation and deletion. It would be nice to extend the programmer's control to permit activity at the endpoints of the object lifetime as well. Is there anything about this (admittedly rough) proposal which violates "Ada theory" (as I like to call it)? Stanley Allen mailto:[log in to unmask]