ijd@otter.hpl.hp.com (Ian J Dickinson) (07/17/90)
This is a small query that needs a big-ish introduction, so skip now if you
don't like big postings.
I have recently (within the last 3 weeks) started learning C++ (using HP's C++
product, but I don't think that's relevant to the problem), and I have come
across the following problem.
I am writing an abstract data-type for a finite map. The range which is any
enumerated type (cast to integers) and the domain is any class which has a
GenericClass as a base class. Now, I want to write one specification of the
interface for a finite map, but have several implementations - in particular a
full map (based on arrays) and a sparse map (based on binary trees). I don't
want to be able to assign one from the other, or anything complicated like
that, but I do want both implementations to exist in the same application (with
different names, obviously).
I thought, when I designed this bit of the code (and at which time I had not
much C++ experience) that I could declare a class for the Map signature:
class Map {
public:
virtual Generic lookupMap( int );
// Return a pointer to the domain object in the map for range element
// alpha. Returns NULL if alpha is not in the range.
virtual Map *mapAdd( int, Generic );
// Adds generic object beta to the range for alpha. The previous
// domain object for alpha (if any) is released. This version is
// referentially transparent, as the old map is left unchanged and a
// new map is returned.
.... etc etc ...
private:
};
and then inherit from it in the implementation classes:
class FullMap : public Map {
public:
FullMap();
// Constructor - initialises main fields. Constructor body allocates
// space for array from heap.
~FullMap();
// Destructor - must free array space and release referenced objects.
private:
FullMap( int );
// Constructor for a known size of map.
Generic *mapArray;
// The array used to implement the mapping
.... etc etc ....
}
and provide implementations for the virtual functions:
// lookupMap
// Return a pointer to the domain object for given range alpha, or NULL
Generic FullMap::lookupMap( int alpha ) {
if (alpha >= mapLength)
return NULL;
else
return (mapArray[ alpha ]);
}
However, the compiler rejects this, saying "lookupMap() is not a member of
FullMap". I interpret this as saying that I must specifically re-declare the
virtual functions that I am providing implementations for (ie all of them) in
the FullMap class definition, which seems to be borne out by the examples in
Lippman (though I can't see a specific statement to that effect). This obviates
the point of having a separate interface class.
So, collected C++ hackers of the world, is there a standard way of providing
one interface and multiple implementations?
BTW - in case the foregoing is too obscure - what I want is something like the
way that, in SML, I can write a signature MAP and two structures:
structure FullMap:MAP = struct ... implementation 1 ... end;
structure SparseMap:MAP = struct ... implementation 2 ... end;
Thanks in advance,
Ian.
|Ian Dickinson HP Labs Bristol (Knowledge Based Programming Dept) England|
|net: ijd@hplb.hpl.hp.com | "Live simply, |
| or: ijd@hplb.uucp | that others may simply live" |
| These opinions are mine, and not (necessarily) HP's or anyone else's. |