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. |