#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();
};
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.
class EX_Foo : public virtual OTC_Resource { };
EX_Foo* foo = new EX_Foo;
foo->reference();
// ...
foo->unReference(); // Item deleted here automatically.
u_int reference() const;
u_int unReference() const;
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.
u_int numRefs() const;
OTC_Resource();
0
.
virtual ~OTC_Resource();
0
. If the count is not
0
, the reference/unreference protocol
has been violated and an exception will
be raised.
inline static void doInOperatorNew();
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
);
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.