WWC snapshot of http://www.alw.nih.gov/Docs/NIHCL/nihcl_8.html taken on Sat Jun 10 19:13:36 1995

Go to the previous, next section.

Class--Class Descriptor

SYNOPSIS

#include <nihcl/Object.h>

BASE CLASS

Object

DERIVED CLASSES

None

RELATED CLASSES

None

DESCRIPTION

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.

CONSTRUCTORS

One of the 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
A list of the addresses of the class descriptors of the base classes of the class being defined.

MEMBER_CLASSES
A list of the addresses of the class descriptors of the non-static member variables of the class being defined that are NIH Library classes. These must be in the same order as they appear in the class declaration.

VIRTUAL_BASE_CLASSES
A list of the addresses of the class descriptors of the virtual base classes of the class being defined.

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)
The 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
`Template_h' and `Template_c' for further details.

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.

ACCESSING CLASS DESCRIPTIONS

static const Class* lookup(const char* name)
Returns a pointer to the class descriptor for class name. Returns 0 if class name is not linked with the program.

const char* name() const
Returns the name of a class.

const Class** baseClasses() const
const Class** memberClasses() const
const Class** virtualBaseClasses() const
Returns a pointer to a zero-terminated list of class descriptor addresses.

const char* ident() const
Returns the identification string of a class.

unsigned long signature() const
Returns the signature of a class. The signature of a class is formed by combining a class's version number with those of its ancestor and non-static member classes during the first call to this function.

virtual unsigned size() const
Returns the size of instances of this class in bytes.

unsigned version() const
Returns the version number of this class.

bool _isKindOf(const Class& cl) const
Returns 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);
}

SEARCHING

virtual unsigned hash() const
Returns the address of this class.

COMPARING CLASSES

virtual int compare(const Object& ob) const
Compares the name of this class with the name of ob, which must also be an instance of class 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.

TESTING CLASSES

virtual bool isEqual(const Object& ob) const
Returns YES if this class and ob are the same; i.e., reside at the same memory address.

COPYING

static bool _deepenVBase(const void* p)
This function is used during deep copy operations to prevent virtual base classes from being "deepened" more than once. It returns 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();
}

PRINTING CLASSES

virtual void dumpOn(ostream& strm =cerr) const
Dumps the following information about this class on strm: class name, identification, version, signature, class number, names of base classes, names of member classes, and names of virtual base classes.

virtual void printOn(ostream& strm =cout) const
Prints this class's name on strm.

OBJECT I/O

Object* readFrom(OIOifd& fd) const
Object* readFrom(OIOin& strm) const
Reads an object from the specified input file descriptor (fd) or stream (strm) into space allocated from the free store, and returns a pointer to the object. To read an object back, a 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));
}

CLASS DICTIONARY

static const Dictionary& dictionary()
Returns a reference to the static class dictionary. All class descriptors loaded into the calling program are stored in the class dictionary during the first call to this function.

DISABLED MEMBER FUNCTIONS

virtual void deepenShallowCopy()
virtual void storer(OIOout&) const
virtual void storer(OIOofd&) const
These functions are implemented as shouldNotImplement().

EXCEPTIONS RAISED

NIHCL_RDBADSIG, NIHCL_RDBADTYP, NIHCL_RDWRONGCLASS, NIHCL_RDUNKCLASS

Go to the previous, next section.