NAME
OTC_Resource -
Base class for objects requiring reference counting.
SYNOPSIS
#include <OTC/refcnt/resource.hh>
class OTC_Resource : public OTC_MPObject
{
public:
u_int reference() const;
u_int unReference() const;
u_int numRefs() const;
virtual ~OTC_Resource();
inline static void doInOperatorNew();
void* operator new(size_t theSize);
void operator delete(void* theMem, size_t theSz);
void* operator new(
size_t theSize,
os_segment* theSegment,
os_typespec* theTypeSpec
);
void* operator new(
size_t theSize,
os_database* theDatabase,
os_typespec* theTypeSpec
);
void* operator new(
size_t theSize,
os_object_cluster* theCluster,
os_typespec* theTypeSpec
);
protected:
OTC_Resource();
};
CLASS TYPE
Abstract
DESCRIPTION
The class OTC_Resource contains support for reference counting.
The reference count allows an object to know how many other
objects hold a reference to it. This allows the object to know
when it is no longer required, so delete itself.
For this to work, users of objects derived from OTC_Resource
must obey a strict protocol. The protocol is that if the user of
the object wishes to hold a reference to the object, the method
reference() must be called. When the user of the object no
longer requires the object, the method unReference() must be
called. After the unReference() method has been called, the
user must not attempt to access the object. If the object is
accessed after unReference() has been called, the result is
undefined. In addition to the above, once the reference()
method has been called, no user of the object should destroy the
object using operator delete(). If an attempt is made to destroy
the object in this way, an exception will be raised.
Objects derived from OTC_Resource should not be created on the
stack, as members of other classes or arrays. The objects should
always be created by using operator new(). If an object is not
created using operator new(), the methods reference() and
unReference() must not be used. If either of the methods are
called, the result is undefined. As this could quite easily occur,
the OTC_Resource class contains code to flag this as an error
and display a warning. To enable the generation of these warning
messages via the log facility, the environment variable
OTCLIB_RESOURCEWARNINGS should be set. Note though, that the
check is disabled when the library is being used in conjunction
with the ObjectStore OODBMS in DML mode.
EXAMPLE
A code example adhering to the protocol described above.
class EX_Foo : public virtual OTC_Resource { };
EX_Foo* foo = new EX_Foo;
foo->reference();
// ...
foo->unReference(); // Item deleted here automatically.
REFERENCE PROTOCOL
u_int reference() const;
Increments by one, the number of objects
which reference this object.
u_int unReference() const;
Decrements by one, the number of objects
which reference this object. If the count
reaches 0 as a result, this object will
delete itself by invoking delete this.
If there are no references to the object,
an exception is raised.
REFERENCED OBJECTS
u_int numRefs() const;
Returns a count of the number of references
to this object.
CONSTRUCTION
OTC_Resource();
Initialises the reference count to 0.
DESTRUCTION
virtual ~OTC_Resource();
Checks that the number of references to
this object is 0. If the count is not
0, the reference/unreference protocol
has been violated and an exception will
be raised.
REFERENCE CHECKS
inline static void doInOperatorNew();
Invoked by the operator new() function
of this class. If a derived class contains
an operator new(), it must include a
call to this function. If
doInOperatorNew() is not called, and
reference() is called in a derived
class, an incorrect warning regarding
referencing of an object not allocated
using operator new() may be generated.
void* operator new(size_t theSize);
void operator delete(void* theMem, size_t theSz);
void* operator new(
size_t theSize,
os_segment* theSegment,
os_typespec* theTypeSpec
);
void* operator new(
size_t theSize,
os_database* theDatabase,
os_typespec* theTypeSpec
);
void* operator new(
size_t theSize,
os_object_cluster* theCluster,
os_typespec* theTypeSpec
);
NOTES
To support the checks for referencing an object that was not
created using operator new(), the method doInOperatorNew() is
invoked from operator new(). If defining an operator new() in
a derived class, you must include a call to the method
doInOperatorNew(). If the call is not included, an exception
will be incorrectly raised when you call reference() on an
instance of the derived class.
LIBRARY
OTC
AUTHOR(S)
Graham Dumpleton
COPYRIGHT
Copyright 1991 1992 1993 OTC LIMITED
Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED