home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!secapl!Cookie!frank
- From: frank@Cookie.secapl.com (Frank Adams)
- Subject: Re: Const Inheritance
- Message-ID: <1992Nov09.162957.31736@Cookie.secapl.com>
- Date: Mon, 09 Nov 1992 16:29:57 GMT
- References: <BwwvMw.DDC@slipknot.rain.com> <1992Nov05.165658.34729@Cookie.secapl.com> <Bx9vsr.4ML@slipknot.rain.com>
- Organization: Security APL, Inc.
- Lines: 100
-
- In article <Bx9vsr.4ML@slipknot.rain.com> robert@slipknot.rain.com.UUCP (Robert Reed) writes:
- >In article <1992Nov05.165658.34729@Cookie.secapl.com> frank@Cookie.secapl.com (Frank Adams) writes:
- >|In article <BwwvMw.DDC@slipknot.rain.com> robert@slipknot.rain.com.UUCP (Robert Reed) writes:
- >|>I have not violated the intended semantics, I have generalized them, within
- >|>reasonable confines of the language.
- >|
- >|Since I'm giving the example, I know what the intended semantics are. If I
- >|am defining the Rectangle class in a context where I can make assertions, I
- >|will assert that setWidth does not change the height, and vice versa. This
- >|is the intended semantics, even though the assertions are not available in
- >|the language.
- >
- > If C++ had declarative
- >assertions, I would expect that placing an assertion on the width and height of
- >a Square should not affect its base Rectangle class.
-
- That isn't the constraint I was referring to. I would put a constraint on
- the setWidth function in the Rectangle class that it not change the height.
- *This* is the assumption that will be violated.
-
- >|void setDimensions(Rectangle& r, int x, int y) {
- >| r.setWidth(x);
- >| r.setHeight(y); // corrected -- originally read setHeight
- >|}
- >|
- >|I expect this function to work: after it is called, r.width() should be x,
- >|and r.height() should be y.
- >
- >(I believe the 2nd setWidth() should be a setHeight().) I see nothing in my
- >counter-proposal which would deny the operation of this function.
-
- But I can do the following:
-
- Square s;
- setDimensions(s, 2, 3);
-
- This does not work; after the call, the width will not be 2. (Of course,
- presented this baldly, I would not expect it to work; but I could be passing
- s to some other function which took a rectangle argument, and called
- setDimensions on it; the resulting bug is quite subtle.)
-
- >|>|> Alternatively, you could make Rectangle a subclass of
- >|>|>Square, define a setPrimaryDimension(int) for Square and add
- >|>|>setSecondaryDimension(int) for the specialized Rectangle class.
- >|
- >|There is another problem with this, if I decide to generalize a bit: I may
- >|want to define:
- >|
- >| template<class WidthT, class HeightT>
- >| class Rectangle {...}
- >|
- >| template<class SideT>
- >| class Square : public Rectangle<SideT, SideT> {...}
- >|
- >|In this case, Rectangle cannot inherit from Square; it would have to change
- >|the types of the instance variables. This is not an altogether artificial
- >|example; I worked on a word processor (not written in an O.O. language) in
- >|which horizontal and vertical distances were expressed in different units.
- >|(This program had no use for squares, however.)
- >
- >If your intent is to use Squares on a system with different horizontal and
- >vertical dimensions, then even your scheme of Const Inheritance doesn't solve
- >the problem. You still have to deal with how to specify a square. Is it
- >expressed in horizontal or vertical units? Or both? If you're going to
- >constrain the problem so as to exclude alternate solutions, make sure your own
- >solution still works.
-
- Sigh. Do I have to explain every little detail? If I were simply using
- different dimensions for width and height, I wouldn't have bothered making a
- template. The point of the template is that I may be using different types
- for the dimensions in different places. For example, I might be using
- character widths and heights in one place, and points in another. I would
- not be able to use Square in the first context, but it would be quite usable
- in the other.
-
- Even more importantly, this is the kind of problem you run into when you
- violate the "isA" relationship in you class hierarchy -- the resulting
- program is fragile. One of the chief advantages of OO programming is that
- later enhancements can be done easily. This kind of fragility makes that
- much more problematic.
-
- >My claim is still that this a brutish approach to a problem that has been
- >solved in many other languages, such as Modula-3, Eiffel, etc.; that is,
- >selective inheritance. As such, const inheritance is a partial feature. In
- >the example we have been abusing, all you really want to restrict is CERTAIN
- >geometry modifying functions--not even all of them. For example, shouldn't I
- >be able to define a Rectangle::setScale() function which could be inherited by
- >Square? It would change variables but not affect the geometric constraints
- >you've expressed concern about. How about a Rectangle::setBoundaryColor()
- >function? This is a nongeometric function and so should be equally usable by
- >Rectangles and Squares.
- >
- >My problem with your proposal is not that it would not provide some useful
- >extention to current syntax. My concern is that your solution only covers a
- >small subset of the problem domain, and as such must be considered a partial
- >feature, a potential source of more frustration than facility.
-
- Selective inheritance might be a useful feature to add to the language. But
- I see const inheritance as a completion of a feature already in the
- language, not as an entirely new feature.
-