Inheritance or delegation or templates {\em -- example}
The choices a designer may be confronted with when
developing a system or a class library may be illustrated
by a simple example.
Suppose that you must develop a system that produces
a quickindex.
A quickindex contains for each line of text
all possible rotations, so that each word can be
rapidly searched for, together with the context in which
it occurs.
The example is taken from [VanVliet], which discusses
a number of alternative solutions from the
perspective of information hiding.
An object oriented solution appears to be surprisingly
simple, in particular when a suitable library is available.
The two classes that are of interest are, respectively,
a class line, to represent each line of text,
and a class index to represent the lines
generated for the quickindex.
}
\sli{
.ds quickindex/line.s
}
\c{
The class line is simply a list of words (strings)
that can be rotated.
The actual implementation of a line is
provided by an instantiation of
a generic (template) class list,
that is contained as a data member,
to which the operations insert and rotate
are delegated.
Instead of incorporating a member of type ,
the line class could have been made a descendant
of the class as indicated below.
class line : public list {
...
};
However, this would make the type line a subtype
of , which does not seem to be a wise decision.
Alternatively, private inheritance could have been employed
as in
class line : private list {
...
};
But, as we have noted before, private inheritance
may also introduce unwanted dependencies.
Explicit delegation seems to be the best solution,
because the relation between a line object
and a list of strings is best characterized
as a uses relation.
}
\sli{
.ds quickindex/index.s
}
\c{
For the index class, a similar argument
as for the line class can be given
why delegation is used instead of public or private
inheritance.
Actually, the most difficult part of the code
is the function defining how to compare two lines
of text, that is needed for sorting the index.
Comparison is based on the lexicographical order.
The ease of implementing both the line and index
class depends largely on the availability of a
powerful list template class.
As discussed in section 2-generic,
when developing generic container classes,
the designer has a choice between using template
classes or relying on inheritance.
}
\nop{
.ds quickindex/lexicographic.s
}
\c{
The reader is invited to work out a solution
with inheritance-based generic lists,
and to check whether his/her solution is as type
safe as the solution presented above.
\nop{
A description of the library used is given in
section \ref{C++libs}.
}
}