Browse Prior Art Database

An Extensible Hierarchical Schema in C++ Using Template Specialization

IP.com Disclosure Number: IPCOM000013525D
Original Publication Date: 2000-Aug-01
Included in the Prior Art Database: 2003-Jun-18
Document File: 16 page(s) / 71K

Publishing Venue

IBM

Abstract

A major drawback of requiring that a model object conform to a particular interface is that it deals poorly with the situation where the implementation of the model is predetermined, perhaps by another group or organization; in this case, a parallel model that conforms to the desired model interface and wraps the original model implementation is needed. Building such a wrapper model can be very expensive and maintaining its consistency with the underlying model can be complex. In addition, in order to write model-specific views, it is typically necessary to access the underlying implementation of a wrapped model object in order to access all of the methods available for the object. This is easily done in Java, with its ability to safely downcast from the root of all classes, namely Object, but in C++, this is not so easy to achieve although safe dynamic casting is now supported in C++, it only works within a class hierarchy derived from a common root and C++ does not provide a unique root class. A solution to the aforementioned problem(s) in C++ is described hereafter. In particular, a technique for specifying a very thin light-weight model wrapper that also supports safe casting to the underlying wrapped implementation of the model is disclosed. It has the additional important benefit of being dynamically extensible through the loading of extension libraries or plugins. The essential idea is to implement a wrapped model object as a pair of values: a generic pointer to the wrapped object and a pointer to a description that can be used to operate on the generic pointer. First, the implementation of a Descriptor: class Descriptor

This text was extracted from a PDF file.
At least one non-text object (such as an image or picture) has been suppressed.
This is the abbreviated version, containing approximately 13% of the total text.

Page 1 of 16

An Extensible Hierarchical Schema in C++ Using Template Specialization

     A major drawback of requiring that a model object conform to a particular interface is that it deals poorly with the situation where the implementation of the model is predetermined, perhaps by another group or organization; in this case, a parallel model that conforms to the desired model interface and wraps the original model implementation is needed. Building such a wrapper model can be very expensive and maintaining its consistency with the underlying model can be complex. In addition, in order to write model-specific views, it is typically necessary to access the underlying implementation of a wrapped model object in order to access all of the methods available for the object. This is easily done in Java, with its ability to safely downcast from the root of all classes, namely Object, but in C++, this is not so easy to achieve - although safe dynamic casting is now supported in C++, it only works within a class hierarchy derived from a common root and C++ does not provide a unique root class.

     A solution to the aforementioned problem(s) in C++ is described hereafter. In particular, a technique for specifying a very thin light-weight model wrapper that also supports safe casting to the underlying wrapped implementation of the model is disclosed. It has the additional important benefit of being dynamically extensible through the loading of extension libraries or plugins.

     The essential idea is to implement a wrapped model object as a pair of values: a generic pointer to the wrapped object and a pointer to a description that can be used to operate on the generic pointer. First, the implementation of a Descriptor:

 class Descriptor
{
public:
typedef sequence<const Descriptor *> Sequence;

Descriptor(const char *type) :

  _type(type)
{
const_cast<Sequence>(descriptors()).push_back(this);
}

const char *type() const
{
return _type;

}

const Sequence &directBaseDescriptors() const
{
return _directBaseDescriptors;

}

const Sequence &directDerivedDescriptors() const
{
return _directDerivedDescriptors;

}

const Sequence &baseDescriptors() const
{
return _baseDescriptors;

}

const Sequence &derivedDescriptors() const
{
return _derivedDescriptors;

}

bool operator==(const Descriptor &descriptor) const
{
return this == &descriptor;

}

bool operator!=(const Descriptor &descriptor) const
{
return this != &descriptor;

}

bool operator<(const Descriptor &descriptor) const
{
return _baseDescriptors.find(&descriptor) != _baseDescriptors.end();
}

bool operator<=(const Descriptor &descriptor) const
{
return _baseDescriptors.find(&descriptor) != _baseDescriptors.end() || *this ==

1

Page 2 of 16

descriptor;

}

bool operator>(const Descriptor &descriptor) const
{
return _derivedDescriptors.find(&descriptor) != _derivedDescriptors.end();
}

  bool operator>=(const Descriptor &descriptor) const
{
return _derivedDescriptors.find(&descriptor) != _derivedDescriptors.end() || *this ==
descriptor;

}

const Descriptor &castToMostDerive...