Go to the previous, next section.
#include <nihcl/Object.h>
Every NIH Library class has a private static member variable named
classDesc
that is an instance of the class named
Class
. This
class descriptor
object contains items of information about an object's class such as its name, base class or classes, member classes, size, and version number. Class
Class
provides member functions for accessing this descriptive information.
Each class descriptor is created by a
DEFINE_CLASS
macro and is initialized by means of a static constructor which links the descriptor, together with other descriptor objects, into a directed acyclic graph (DAG) that reflects the organization of the NIH Library classes loaded with a program. Program initialization stores class descriptors in a static container called the
class dictionary, accessible to application programs by means member function
Class::dictionary()
, which allows a class descriptor to be found given the name of the class.
DEFINE_CLASS
macros is used to construct the class descriptor for an NIH Library class.However, before calling one of these macros, you must first define three preprocessor symbols to describe the relationship of the class you are defining to other NIH Library classes.
BASE_CLASSES
MEMBER_CLASSES
VIRTUAL_BASE_CLASSES
For example:
class X: public A, public virtual B { C c; // C is an NIH Library class D d; // D is an NIH Library class // ... }; #define BASE_CLASSES A::desc(), B::desc() #define MEMBER_CLASSES C::desc(), D::desc() #define VIRTUAL_BASE_CLASSES B::desc()
There are four variants of the
DEFINE_CLASS
macro:
DEFINE_CLASS(classname,version,identification,initor)
DEFINE_ABSTRACT_CLASS(classname,version,identification,initor)
DEFINE_CLASS_MI(classname,version,identification,initor)
DEFINE_ABSTRACT_CLASS_MI(classname,version,identification,initor)
DEFINE_CLASS
macro defines the instance of class
Class
that describes the class you are defining and defines common member functions such as
isA()
,
shallowCopy()
,
deepenVBase()
, and
storeVBaseOn()
. Use
DEFINE_ABSTRACT_CLASS
or
DEFINE_ABSTRACT_CLASS_MI
to define abstract classes, and use
DEFINE_CLASS_MI
or
DEFINE_ABSTRACT_CLASS_MI
to define classes with multiple base classes. See
Classname is the name of the class you are defining.
Version
is the version number of the class you are defining. You should increment this number whenever the format written by the class's
storer()
function changes such that older versions of
readFrom()
can no longer interpret it correctly. This prevents outdated versions of objects from being read incorrectly.
Identification
is a character string that identifies the revision level of the implementation of the class. You can retrieve it by calling the function
Class::ident()
.
Initor
is a pointer to a function you may supply to perform initialization for the class, for example, initializing static data that the class uses. This static function takes a reference to the class's class descriptor (a
const Class&
) as an argument:
typedef void (*initorTy)(const Class&);
The constructor for class
Class
calls
initor
just before returning. Since these constructors are called statically, you cannot predict the order in which
Initor
functions will be called.
static const Class* lookup(const char*
name)
const char* name() const
const Class** baseClasses() const
const Class** memberClasses() const
const Class** virtualBaseClasses() const
const char* ident() const
unsigned long signature() const
virtual unsigned size() const
unsigned version() const
bool _isKindOf(const Class&
cl) const
YES
if this class or any of its ancestors has the same class descriptor address as
cl.
_isKindOf()
is used to implement
Object::isKindOf()
:
bool Object::isKindOf(const Class& clid) const { return isA()->_isKindOf(clid); }
virtual unsigned hash() const
virtual int compare(const Object&
ob) const
Class
. Returns a negative result if this class is alphabetically before
ob, zero if the class names are the same, and a positive result if this class is alphabetically after
ob.
virtual bool isEqual(const Object&
ob) const
YES
if this class and
ob
are the same; i.e., reside at the same memory address.
static bool _deepenVBase(const void*
p)
YES
if it has not been called previously during a deep copy operation for the object at address
p.
The
DEFINE_CLASS
macros define the
deepenVBase()
function for class
X
in terms of
Class::_deepenVBase()
as:
void X::deepenVBase() { if (Class::_deepenVBase((const void*)this)) X::deepenShallowCopy(); }
virtual void dumpOn(ostream&
strm
=cerr) const
virtual void printOn(ostream&
strm
=cout) const
Object* readFrom(OIOifd&
fd) const
Object* readFrom(OIOin&
strm) const
OIOifd
or
OIOin
class compatible with the
OIOofd
or
OIOout
class used to store the object must be used.
The
DEFINE_MEMBERS
macro defines the static member
readFrom()
functions for a class
X
in terms of
Class::readFrom()
as:
static X* readFrom(OIOifd& fd) { return castdown(desc()->readFrom(fd)); } static X* readFrom(OIOin& strm) { return castdown(desc()->readFrom(strm)); }
static const Dictionary& dictionary()
virtual void deepenShallowCopy()
virtual void storer(OIOout&) const
virtual void storer(OIOofd&) const
shouldNotImplement()
.
NIHCL_RDBADSIG
,
NIHCL_RDBADTYP
,
NIHCL_RDWRONGCLASS
,
NIHCL_RDUNKCLASS
Go to the previous, next section.