|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-06-19 17:40:43
Hello all,
I have written a small library that performs base class injection, which
essentially allows the user to take a class A and "inject' it as a base class
of some other class R. The injection is done without modifying R's source
code, so it is a powerful method of separating concerns. The following
example is paraphrased from the paper at:
http://www.cs.rpi.edu/~gregod/papers/base_class_injection.ps
which describes the concept much more cleanly. The library itself is located
at:
http://www.cs.rpi.edu/~gregod/libraries/injection.zip
Consider a GUI hierarchy, which contains a Widget base class with a derived
class Button with a descendant class CheckBox, so we have something akin to:
class Widget { /* ... */ };
class Button : public Widget{ /* ... */ };
class CheckBox : public Button { /* ... */ };
Now, we want to add support for a new interface type (i.e., an audible
interface). The new interface looks like this:
class AudibleDescription {
public:
virtual AudioText audibleDescription() = 0;
};
Generally, we would have Widget inherit AudibleDescription and then override
the audibleDescription function in each of Widget's child classes with an
appropriate implementation. Instead, lets keep the implementations of the
audible interface completely separate.
class AudibleButton : public virtual AudibleDescription {
virtual AudioText audibleDescription() {
/* use a text-to-speech synthesizer on the button's label */
}
};
class AudibleCheckBox : public virtual AudibleButton {
virtual AudioText audibleDescription() {
/* use text-to-speech synthesizer on label, and add a comment telling if
the checkbox is selected or not */
}
};
Now the audible interface to the widget library is completely separate from
the widget library itself. Now we would like to include the new audible
interface in with the widget library. Base class injection lets us make
AudibleDescription a base class of Widget, AudibleButton a base class of
Button, and AudibleCheckBox a base class of CheckBox. Now our widget library
conforms to the new interface but retains its old types and behavior.
Base class injection has the capability to make a library more adaptive. For
instance, some C++ garbage collectors require garbage-collected types to
derive from a specific class (e.g., 'gc'). Try to use an STL component with
garbage collection and you end up creating a wrapper for each STL component
because you can't add a base class. If STL components were instead built to
support base class injection (the changes are trivial), a user would be free
to inject base classes into the STL components to make them more
environment-aware. An injection of 'gc' into an STL vector would look
something like:
template<typename T, typename Allocator>
struct bases<std::vector<T, Allocator>, 0> {
typedef gc base;
};
Is there interest for this technique within Boost?
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk