NAME
HandleId - data used by Handle to track pointers to an object
INCLUDE
include "HandleId.h"
SYNTAX
class HandleId
{
protected:
static int name_counter; // used to assign value to name_code
int refcount; // reference count
char dynamic_object; // '1': explicit call to new created the object
#ifdef SAFETY_CHECKS // indicates non-optimized version
int name_code; // a number identifies a name of the object
String name_str; // name of variable managed by a handle
String class_tp; // class type of variable managed by a handle
size_t mem_size; // no of bytes allocated (to recognize the obj.)
bool trace_me; // indicates verbose (debug) mode
#endif
public:
HandleId ();
virtual ~HandleId ();
static int howManyHandles() { return name_counter; }
bool isReferenced () const { return getbool(refcount != 0); }
int getNoRefs () const { return refcount; }
bool dynamicObj () const { return getbool(dynamic_object=='1'); }
#ifdef SAFETY_CHECKS
int getNameCode () const { return name_code; }
bool hasClassType () const;
void setClassType (const char* class_tp);
// possibly verbose functions for non-optimized compilation:
void increment (); // refcount++
void decrement (); // refcount--
private:
void identity (); // write the HandleId info on identity to cout
public:
#else
// efficient inline functions for optimized compilation:
void increment () { refcount++; }
void decrement () { refcount--; }
#endif
void traceMe (const char* name_of_variable);
void* operator new (size_t t);
void* operator new (size_t t, const char* /*filename*/, int /*lineno*/);
void operator delete (void* v);
};
KEYWORDS
smart pointer, memory management, allocation, deallocation,
delete, handle
DESCRIPTION
The class provides the data structure for reference counting (and
debugging of reference counting) when using handles. The class to
be handled must be derived from HandleId (using public virtual
declaration).
CONSTRUCTORS AND INITIALIZATION
There is a constructor without arguments. No initialization
beyond that is necessary.
NOTE: The size of class HandleId objects depend on preprocessor
(cpp) variables! Check the class definition carefully. When using
BasicTools/Diffpack makefiles, no inconsistencies should occur
unless one defines SAFETY_CHECKS for an application while compil
ing in optimized mode (this will lead to an error since the
application sees a larger HandleId object than what is used in
the optimized libraries, recall that SAFETY_CHECKS is undefined
in optimized libraries).
MEMBER FUNCTIONS
isReferenced - returns true if there are pointers pointing to the
present object. Here present object means the object of the sub
class derived from HandleId, that is, the object to be handled by
a handle.
increment - increases the reference counter by one reference.
decrement - decreases the reference counter by one reference.
getNoRefs - returns the number of references.
getNameCode - returns the "name" of the object that is handled.
Each object is assigned an integer number. This number is the
object's name and can be used when debugging handles to objects.
Normally, a programmer has no need for this feature - the present
version of the handle features is well tested!
"setClassType - used to set the class type that has this HandleId
as base class. The function is called from the Handle class func
tions when compiling in non-optimized mode. The effect is error
messages that are easier to interpret.
hasClassType - returns true if setClassType has been called for
this object. Used to avoid repeated calls to setClassType from
the Handle class member functions.
"dynamicObj - returns true if the object was created by a call to
new rather than being declared as an instance (e.g., X x;). This
function is important: Handles should only delete objects that
were created by an explicit call to new. C++ will automatically
delete objects that go out of scope the normal way.
new - a special new function written to determine if the object
was created by new. Note that if a class X is derived from Han
dleId, the statement new X leads to a call to HandleId::new. A
declaration X x will create the object using the global ::new
function.
delete - the counter part to the local new.
traceMe - if the non-optimized compilation mode is used (that is,
the preprocessor variable SAFETY_CHECKS is defined), the traceMe
function writes a message every time the object (subclass of Han
dleId) is allocated, referenced, dereferenced or deleted. This
may help to track down memory leakage for example. The arguments
to traceMe are a name of the variable being managed by the handle
(the name makes it easier to follow the debug output than just
the integer in the name_code variable).
howManyHandles - returns the total number of handles created so
far in an execution.
DEVELOPED BY
SINTEF Applied Mathematics, Oslo, Norway, and University of Oslo,
Dept. of Mathematics, Norway
AUTHOR
Hans Petter Langtangen, SINTEF/UiO