// STATIC method
template<class T> Handle
dynamic<T>::activate (const char *libraryName,
const char *className = NULL) throw(...)
{
// special interface method provides default class name
if (className == NULL) {
className = T::getClassName();
}
// for simplicity: only the code that handles the FIRST
// activation of this class, DynamicVersion constructor
// inlined, and no error checking
DynamicVersion *dv = new DynamicVersion;
dv->activeVersion = true;
dv->refCount = 0;
dv->dlhandle = dlopen(libraryName,RTLD_NOW);
dv->dlloaded = true;
// omitted: construct funcName (= name of static
// factory method that creates implementation object)
dv->funcPtr = dlsym(dvPtr->dlhandle,funcName);
dv->invalidated = false;
// now we have an active version for this class
Handle handle = handleMap->createHandle(className);
activeMap[handle] = dv;
return (handle);
}
template<class T>
dynamic<T>::dynamic (Handle handle) throw(...)
{
// omitted: all error checking
// classHandle, dvPtr, object are per-instance member
// variables (see Figure 1)
classHandle = handle;
dvPtr = activeMap[handle];
object = (T *)(*(dvPtr->funcPtr))();
dvPtr -> refCount += 1;
}
template <class T>
T * dynamic<T>::operator-> (void) throw(...)
{
if (dvPtr->invalidated) { throw ...; }
return (object);
}