|
Boost : |
From: Daniel James (daniel_at_[hidden])
Date: 2005-02-27 06:50:32
Jonathan Wakely wrote:
>>It's generally a bad idea to inherit from concrete classes that weren't
>>designed to be inherited from, not just STL containers.
Jeff Garland wrote:
> Well again, to me there are other cases in the design of concrete classes
> where there is some advantage in inheriting from a base class with a
> non-virtual destructor. For example in date-time some time duration classes
> are derive from a base class with no virtual destructor. These subclasses are
> simply a constructor the adjust for precision. So for example:
>
[snip]
> So a few simple conversion classes help our cause:
>
> class seconds : public time_duration
> {
> seconds(int s) : time_duration(0,0,s,0) {}
> };
>
> class milliseconds : public time_duration
> {
> milliseconds(int s) : time_duration(0,0,0,s) {}
> };
>
> Now we can write:
>
> //code with obvious meaning
> time_duration td = seconds(10) + milliseconds(10);
You're the designer of the base class - so it is designed to be
inherited from. You're not overriding the public interface, so you'll
get the same behaviour from the base class and the derived class. I
wouldn't feel great about this code, but I find it hard to come up with
a really convincing argument against it.
I suppose there are alternatives: a function which returns time_duration
(but then you can't overload on the type) or a class with conversion
operators to time_duration (but that falls down when a function overload
requires more user-defined conversions).
If you wanted to do something like this, but were worried about it, how
much work would it be to remove all possibilities of undefined
behaviour? At least under reasonable use, that is. Or is it even
possible? I suppose you'd have to make operators &, new and delete
protected, anything else? (I'm thinking about something along the lines
of boost::noncopyable).
Jonathan Wakely wrote:
>>In fact, it's generally a bad idea to use public inheritance to model
>>anything except substitutablity. Inheritance creates one of the
>>strngest coupling between two classes you can have, and reducing
>>coupling is usually a good idea.
Christopher is trying to model substitutability, I think.
Jeff Garland wrote:
> I'd say there is something about writing less code (not laziness) that makes
> it a better design. Having to forward or reimplement the whole interface of
> an stl container is non-trivial and probably a bad design.
In Christopher's use case, he's wrapping most of the member functions
anyway.
Daniel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk