Top: Basic types: unknown & component

>     #include <ptypes.h>

>     class unknown {
>         unknown();
>         virtual ~unknown();
>     }

>     class component {
>         component();
>         virtual ~component();
>         void addnotification(component* c);
>         void delnotification(component* c);
>         virtual void freenotify(component* c);
>     }

>     component* addref(component*);
>     bool release(component*);

>     template <class T> class compref;

>     int objalloc;

The unknown interface is the base for all interfaces (classes) in PTypes, except string, cset, variant, mutex, rwlock, msgqueue and tpodlist. The unknown class has no semantic or functional meaning, except that deriving a class from unknown provides a simple mechanism of tracking the number of created/destroyed objects in a program. Historically, unknown was used in PTypes as a base for all list item types, however, starting from version 2.0 of the library this requirement is no longer in place.

The component class adds reference-counting functionality to unknown (see addref() and release() below). PTypes variants require objects to be derived from component instead of unknown to be able to make assignments and destruction of variants properly. See also compref below.

As an alternative to reference-counting component also provides so-called 'delete notification' mechanism. If object A holds a reference to object B, A can add itself to B's notification list to be notified when B is being destroyed. This allows A to take appropriate actions, e.g. invalidate the reference to B. A in this case can declare reference to B as a plain pointer. In other words, A should override its own virtual method freenotify(), and it also should call addnotification(this) for the object it holds reference to.

All stream objects in PTypes and aslo the unit class are derived from component.

A global variable objalloc is declared to keep track of the number of allocated objects (derived from unknown or component) in an application program, which can help you to find memory leaks or other potential bugs. The allocation counting works only in DEBUG mode. If the memory is cleaned up properly, this value should be zero upon program termination. You can write code, possibly enclosed within #ifdef DEBUG ... #endif, which checks whether this value is zero at the end of main().

These interfaces are declared in <ptypes.h>.

component* addref(component* c) increments the reference counter for the given component object c. The return value is the same as c and is provided for convenience.

bool release(component* c) decrements the reference counter and destroys the object c if the counter reached 0. Returns true if the object has been destroyed. Passing NULL to this function is not an error.

template <class T> class compref implements a 'smart' pointer to component (or any derivative class) with automatic reference counting. Use this template in place of a plain pointer declaration (e.g. compref<myclass> instead of myclass*) to automatically destroy objects as soon as there are no more references left. The behavior of compref pointers is similar to plain pointers, except that they perform additional actions when assigning new values to them.

virtual component::~component() destroys the component and calls freenotify() for each object in the notification list.

component::addnotification(component* c) adds object c to the notification list of this object. This object's destructor will then call c->freenotify().

component::delnotification(component* c) deletes object c from this object's notification list.

virtual component::freenotify(component* caller) is being called by the caller's destructor for each object in the notification list. This method should be overriden in classes which add themselves to other objects' notification lists. The overridden method usually invalidates (assigns NULL) all references to caller.

See also: Lists, variant

PTypes home