Re: Deriving from concrete types
kanze wrote:
Gene Bushuyev wrote:
<snip>
Inheriting from a large concrete class like std::vector is a
gratuitous violation of design rules, which has only
problems and no real advantages.
... There is also no doubt in my mind that std::vector<>
was not so designed, and that any use of it as a public base
class will run into problems. Not because it doesn't
conform to the rules of the OO design concept, per se, but
because it doesn't conform to the rules of any design
concept which would normally be implemented using it as a
base class in C++.
It's funny. When I first added my $0.02 to this
discussion, I didn't have a concrete example. I was
merely responding to what I saw as overly rigid dogma.
However, just in the last hour, I find myself writing a class
which is publicly derived from std::vector .
The situation is that I have a class to implement a configuration
table. The (private) member object that holds the table data was
originally
typedef std::vector<Entry> KeywordData
std::vector<KeywordData> tableData;
(If anyone cares, Entry is basically a bag of data.)
Another part of the class maps the keyword to the index in
"tableData".
Writing the code to set up and to access the data went
quickly, because I (and anyone who maintains the code)
know all about how to use std::vector<> (well, almost all....)
I then went to write my "print()" function, which prints out
the contents of the table for debugging purposes,
(one of my design principles: never create a complicated
data structure without a "print()" function!) and
realized that "tableData" didn't have the keyword.
At first, in line with the suggestions in this thread, I tried
making KeywordData a class:
struct KeywordData { std::vector<Entry> data; std::string keyword; };
Why? Why is it so essential that the print function be a
member? Especially here, where the type is a member of a larger
class anyway?
but since I wanted to preserve the interface, I found
myself writing forwarding functions for large parts of
the std::vector interface, with frequent trips to the
std::vector man page to get all the types just right.
Again, since the type is an implementation detail of
configuration table. As such, there is absolutely no reason to
provide more interface than absolutely necessary. Any
additional interface is, in fact, a design error. (If the
additional interface is present because you are using a typedef,
fine. As long as the type remains private, you're still in
control. As soon as the type becomes public, however, you
definitly want to restrict the interface to be as narrow as
possible.)
On the whole, I'd say that you are following overly rigid dogma.
And that one of those dogma is even bad---it imposes something
you normally want to avoid.
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]